summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/5a/a.h48
-rw-r--r--src/cmd/5a/a.y30
-rw-r--r--src/cmd/5a/lex.c377
-rw-r--r--src/cmd/5a/y.tab.c981
-rw-r--r--src/cmd/5a/y.tab.h38
-rw-r--r--src/cmd/5c/gc.h83
-rw-r--r--src/cmd/5c/list.c303
-rw-r--r--src/cmd/5c/peep.c44
-rw-r--r--src/cmd/5c/reg.c20
-rw-r--r--src/cmd/5c/swt.c285
-rw-r--r--src/cmd/5c/txt.c44
-rw-r--r--src/cmd/5g/cgen.c66
-rw-r--r--src/cmd/5g/galign.c9
-rw-r--r--src/cmd/5g/gg.h50
-rw-r--r--src/cmd/5g/ggen.c195
-rw-r--r--src/cmd/5g/gobj.c264
-rw-r--r--src/cmd/5g/gsubr.c66
-rw-r--r--src/cmd/5g/list.c342
-rw-r--r--src/cmd/5g/opt.h1
-rw-r--r--src/cmd/5g/peep.c156
-rw-r--r--src/cmd/5g/prog.c10
-rw-r--r--src/cmd/5g/reg.c267
-rw-r--r--src/cmd/5l/5.out.h85
-rw-r--r--src/cmd/5l/asm.c1542
-rw-r--r--src/cmd/5l/l.h349
-rw-r--r--src/cmd/5l/list.c427
-rw-r--r--src/cmd/5l/noop.c671
-rw-r--r--src/cmd/5l/obj.c731
-rw-r--r--src/cmd/5l/optab.c277
-rw-r--r--src/cmd/5l/pass.c409
-rw-r--r--src/cmd/5l/prof.c211
-rw-r--r--src/cmd/5l/softfloat.c91
-rw-r--r--src/cmd/5l/span.c937
-rw-r--r--src/cmd/6a/a.h54
-rw-r--r--src/cmd/6a/a.y28
-rw-r--r--src/cmd/6a/lex.c382
-rw-r--r--src/cmd/6a/y.tab.c1457
-rw-r--r--src/cmd/6a/y.tab.h50
-rw-r--r--src/cmd/6c/gc.h75
-rw-r--r--src/cmd/6c/list.c355
-rw-r--r--src/cmd/6c/peep.c16
-rw-r--r--src/cmd/6c/reg.c31
-rw-r--r--src/cmd/6c/sgen.c2
-rw-r--r--src/cmd/6c/swt.c297
-rw-r--r--src/cmd/6c/txt.c75
-rw-r--r--src/cmd/6g/cgen.c100
-rw-r--r--src/cmd/6g/galign.c28
-rw-r--r--src/cmd/6g/gg.h49
-rw-r--r--src/cmd/6g/ggen.c236
-rw-r--r--src/cmd/6g/gobj.c260
-rw-r--r--src/cmd/6g/gsubr.c104
-rw-r--r--src/cmd/6g/list.c364
-rw-r--r--src/cmd/6g/opt.h1
-rw-r--r--src/cmd/6g/peep.c26
-rw-r--r--src/cmd/6g/prog.c7
-rw-r--r--src/cmd/6g/reg.c253
-rw-r--r--src/cmd/6l/6.out.h44
-rw-r--r--src/cmd/6l/asm.c299
-rw-r--r--src/cmd/6l/l.h374
-rw-r--r--src/cmd/6l/list.c396
-rw-r--r--src/cmd/6l/obj.c701
-rw-r--r--src/cmd/6l/optab.c1369
-rw-r--r--src/cmd/6l/pass.c991
-rw-r--r--src/cmd/6l/prof.c171
-rw-r--r--src/cmd/6l/span.c1846
-rw-r--r--src/cmd/8a/a.h55
-rw-r--r--src/cmd/8a/a.y26
-rw-r--r--src/cmd/8a/lex.c380
-rw-r--r--src/cmd/8a/y.tab.c1446
-rw-r--r--src/cmd/8a/y.tab.h50
-rw-r--r--src/cmd/8c/gc.h75
-rw-r--r--src/cmd/8c/list.c316
-rw-r--r--src/cmd/8c/peep.c16
-rw-r--r--src/cmd/8c/reg.c29
-rw-r--r--src/cmd/8c/swt.c273
-rw-r--r--src/cmd/8c/txt.c49
-rw-r--r--src/cmd/8g/cgen.c43
-rw-r--r--src/cmd/8g/galign.c9
-rw-r--r--src/cmd/8g/gg.h47
-rw-r--r--src/cmd/8g/ggen.c175
-rw-r--r--src/cmd/8g/gobj.c259
-rw-r--r--src/cmd/8g/gsubr.c69
-rw-r--r--src/cmd/8g/list.c316
-rw-r--r--src/cmd/8g/opt.h3
-rw-r--r--src/cmd/8g/peep.c24
-rw-r--r--src/cmd/8g/prog.c21
-rw-r--r--src/cmd/8g/reg.c261
-rw-r--r--src/cmd/8l/8.out.h50
-rw-r--r--src/cmd/8l/asm.c393
-rw-r--r--src/cmd/8l/l.h330
-rw-r--r--src/cmd/8l/list.c313
-rw-r--r--src/cmd/8l/obj.c698
-rw-r--r--src/cmd/8l/optab.c1030
-rw-r--r--src/cmd/8l/pass.c858
-rw-r--r--src/cmd/8l/prof.c173
-rw-r--r--src/cmd/8l/span.c1507
-rw-r--r--src/cmd/addr2line/addr2line_test.go115
-rw-r--r--src/cmd/addr2line/main.c90
-rw-r--r--src/cmd/addr2line/main.go253
-rw-r--r--src/cmd/api/goapi.go2
-rw-r--r--src/cmd/api/run.go4
-rw-r--r--src/cmd/cc/cc.h38
-rw-r--r--src/cmd/cc/lex.c127
-rw-r--r--src/cmd/cc/lexbody76
-rw-r--r--src/cmd/cc/macbody56
-rw-r--r--src/cmd/cc/pgen.c133
-rw-r--r--src/cmd/cc/pswt.c29
-rw-r--r--src/cmd/cc/sub.c10
-rw-r--r--src/cmd/cgo/doc.go28
-rw-r--r--src/cmd/cgo/gcc.go84
-rw-r--r--src/cmd/cgo/out.go47
-rw-r--r--src/cmd/dist/a.h5
-rw-r--r--src/cmd/dist/arm.c12
-rw-r--r--src/cmd/dist/build.c267
-rw-r--r--src/cmd/dist/buildgc.c10
-rw-r--r--src/cmd/dist/buildgo.c2
-rw-r--r--src/cmd/dist/buildruntime.c98
-rw-r--r--src/cmd/dist/goc2c.c116
-rw-r--r--src/cmd/dist/unix.c9
-rw-r--r--src/cmd/dist/windows.c22
-rw-r--r--src/cmd/gc/align.c10
-rw-r--r--src/cmd/gc/array.c129
-rw-r--r--src/cmd/gc/bits.c2
-rw-r--r--src/cmd/gc/builtin.c30
-rw-r--r--src/cmd/gc/bv.c134
-rw-r--r--src/cmd/gc/closure.c20
-rw-r--r--src/cmd/gc/const.c92
-rw-r--r--src/cmd/gc/dcl.c28
-rw-r--r--src/cmd/gc/doc.go6
-rw-r--r--src/cmd/gc/esc.c190
-rw-r--r--src/cmd/gc/export.c5
-rw-r--r--src/cmd/gc/fmt.c115
-rw-r--r--src/cmd/gc/gen.c95
-rw-r--r--src/cmd/gc/go.h126
-rw-r--r--src/cmd/gc/go.y6
-rw-r--r--src/cmd/gc/inl.c3
-rw-r--r--src/cmd/gc/lex.c97
-rw-r--r--src/cmd/gc/md5.c4
-rw-r--r--src/cmd/gc/md5.h2
-rw-r--r--src/cmd/gc/mparith1.c44
-rw-r--r--src/cmd/gc/mparith2.c10
-rw-r--r--src/cmd/gc/mparith3.c115
-rw-r--r--src/cmd/gc/obj.c281
-rw-r--r--src/cmd/gc/order.c930
-rw-r--r--src/cmd/gc/pgen.c398
-rw-r--r--src/cmd/gc/plive.c1985
-rw-r--r--src/cmd/gc/popt.c79
-rw-r--r--src/cmd/gc/racewalk.c3
-rw-r--r--src/cmd/gc/range.c77
-rw-r--r--src/cmd/gc/reflect.c149
-rw-r--r--src/cmd/gc/runtime.go31
-rw-r--r--src/cmd/gc/select.c116
-rw-r--r--src/cmd/gc/sinit.c98
-rw-r--r--src/cmd/gc/subr.c63
-rw-r--r--src/cmd/gc/swt.c2
-rw-r--r--src/cmd/gc/typecheck.c255
-rw-r--r--src/cmd/gc/walk.c453
-rw-r--r--src/cmd/gc/y.tab.c1762
-rw-r--r--src/cmd/gc/y.tab.h46
-rw-r--r--src/cmd/go/build.go626
-rw-r--r--src/cmd/go/clean.go41
-rw-r--r--src/cmd/go/context.go36
-rw-r--r--src/cmd/go/discovery.go3
-rw-r--r--src/cmd/go/doc.go116
-rw-r--r--src/cmd/go/env.go34
-rw-r--r--src/cmd/go/get.go11
-rw-r--r--src/cmd/go/help.go46
-rw-r--r--src/cmd/go/list.go55
-rw-r--r--src/cmd/go/main.go6
-rw-r--r--src/cmd/go/pkg.go33
-rw-r--r--src/cmd/go/pkg_test.go73
-rw-r--r--src/cmd/go/run.go39
-rw-r--r--src/cmd/go/signal_unix.go2
-rwxr-xr-xsrc/cmd/go/test.bash211
-rw-r--r--src/cmd/go/test.go142
-rw-r--r--src/cmd/go/testdata/cgocover/p.go19
-rw-r--r--src/cmd/go/testdata/cgocover/p_test.go7
-rw-r--r--src/cmd/go/testdata/dep_test.go7
-rw-r--r--src/cmd/go/testdata/src/notest/hello.go6
-rw-r--r--src/cmd/go/testdata/src/testcycle/p1/p1.go7
-rw-r--r--src/cmd/go/testdata/src/testcycle/p1/p1_test.go6
-rw-r--r--src/cmd/go/testdata/src/testcycle/p2/p2.go7
-rw-r--r--src/cmd/go/testdata/src/testcycle/p3/p3.go5
-rw-r--r--src/cmd/go/testdata/src/testcycle/p3/p3_test.go10
-rw-r--r--src/cmd/go/testdata/src/xtestonly/f.go3
-rw-r--r--src/cmd/go/testdata/src/xtestonly/f_test.go12
-rw-r--r--src/cmd/go/testdata/standalone_test.go6
-rw-r--r--src/cmd/go/testdata/testonly/p_test.go1
-rw-r--r--src/cmd/go/testflag.go23
-rw-r--r--src/cmd/go/vcs.go10
-rw-r--r--src/cmd/gofmt/doc.go11
-rw-r--r--src/cmd/gofmt/gofmt.go39
-rw-r--r--src/cmd/gofmt/gofmt_test.go1
-rw-r--r--src/cmd/gofmt/long_test.go2
-rw-r--r--src/cmd/gofmt/rewrite.go27
-rw-r--r--src/cmd/gofmt/testdata/typeswitch.golden2
-rw-r--r--src/cmd/gofmt/testdata/typeswitch.input2
-rw-r--r--src/cmd/ld/data.c714
-rw-r--r--src/cmd/ld/decodesym.c109
-rw-r--r--src/cmd/ld/doc.go4
-rw-r--r--src/cmd/ld/dwarf.c602
-rw-r--r--src/cmd/ld/dwarf.h8
-rw-r--r--src/cmd/ld/elf.c277
-rw-r--r--src/cmd/ld/elf.h15
-rw-r--r--src/cmd/ld/go.c157
-rw-r--r--src/cmd/ld/ldelf.c64
-rw-r--r--src/cmd/ld/ldmacho.c56
-rw-r--r--src/cmd/ld/ldpe.c60
-rw-r--r--src/cmd/ld/lib.c1625
-rw-r--r--src/cmd/ld/lib.h388
-rw-r--r--src/cmd/ld/macho.c123
-rw-r--r--src/cmd/ld/pass.c104
-rw-r--r--src/cmd/ld/pcln.c244
-rw-r--r--src/cmd/ld/pe.c212
-rw-r--r--src/cmd/ld/pe.h2
-rw-r--r--src/cmd/ld/pobj.c197
-rw-r--r--src/cmd/ld/symtab.c244
-rw-r--r--src/cmd/ld/textflag.h2
-rw-r--r--src/cmd/nm/Makefile5
-rw-r--r--src/cmd/nm/debug_goobj.go670
-rw-r--r--src/cmd/nm/doc.go56
-rw-r--r--src/cmd/nm/elf.go57
-rw-r--r--src/cmd/nm/goobj.go67
-rw-r--r--src/cmd/nm/macho.go69
-rw-r--r--src/cmd/nm/nm.c401
-rw-r--r--src/cmd/nm/nm.go184
-rw-r--r--src/cmd/nm/nm_test.go99
-rw-r--r--src/cmd/nm/pe.go98
-rw-r--r--src/cmd/nm/plan9obj.go48
-rw-r--r--src/cmd/objdump/Makefile10
-rw-r--r--src/cmd/objdump/armasm.go10821
-rw-r--r--src/cmd/objdump/elf.go65
-rw-r--r--src/cmd/objdump/macho.go77
-rw-r--r--src/cmd/objdump/main.c68
-rw-r--r--src/cmd/objdump/main.go519
-rw-r--r--src/cmd/objdump/objdump_test.go193
-rw-r--r--src/cmd/objdump/pe.go99
-rw-r--r--src/cmd/objdump/plan9obj.go63
-rw-r--r--src/cmd/objdump/testdata/fmthello.go7
-rw-r--r--src/cmd/objdump/x86.go13800
-rw-r--r--src/cmd/pack/Makefile5
-rw-r--r--src/cmd/pack/ar.c1727
-rw-r--r--src/cmd/pack/doc.go40
-rw-r--r--src/cmd/pack/pack.go486
-rw-r--r--src/cmd/pack/pack_test.go402
-rw-r--r--src/cmd/yacc/Makefile8
-rw-r--r--src/cmd/yacc/expr.y2
-rw-r--r--src/cmd/yacc/yacc.go15
248 files changed, 42023 insertions, 33800 deletions
diff --git a/src/cmd/5a/a.h b/src/cmd/5a/a.h
index 8b39d610f..bb60fe7de 100644
--- a/src/cmd/5a/a.h
+++ b/src/cmd/5a/a.h
@@ -29,6 +29,7 @@
// THE SOFTWARE.
#include <bio.h>
+#include <link.h>
#include "../5l/5.out.h"
#ifndef EXTERN
@@ -43,9 +44,7 @@
#define ungetc ccungetc
typedef struct Sym Sym;
-typedef struct Gen Gen;
typedef struct Io Io;
-typedef struct Hist Hist;
#define MAXALIGN 7
#define FPCHIP 1
@@ -88,33 +87,6 @@ struct Io
};
#define I ((Io*)0)
-EXTERN struct
-{
- Sym* sym;
- short type;
-} h[NSYM];
-
-struct Gen
-{
- Sym* sym;
- int32 offset;
- int32 offset2;
- short type;
- short reg;
- short name;
- double dval;
- char sval[8];
-};
-
-struct Hist
-{
- Hist* link;
- char* name;
- int32 line;
- int32 offset;
-};
-#define H ((Hist*)0)
-
enum
{
CLAST,
@@ -125,13 +97,11 @@ enum
Always = 14,
};
-EXTERN char debug[256];
+EXTERN int debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
-EXTERN Hist* ehist;
EXTERN int newflag;
-EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
@@ -142,10 +112,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
-EXTERN Gen nullgen;
+EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
-EXTERN char* pathname;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
@@ -155,6 +124,8 @@ EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
+EXTERN Link* ctxt;
+EXTERN Biobuf bstdout;
void* alloc(int32);
void* allocn(void*, int32, int32);
@@ -174,11 +145,8 @@ int escchar(int);
void cinit(void);
void pinit(char*);
void cclean(void);
-int isreg(Gen*);
-void outcode(int, int, Gen*, int, Gen*);
-void zname(char*, int, int);
-void zaddr(Gen*, int);
-void ieeedtod(Ieee*, double);
+int isreg(Addr*);
+void outcode(int, int, Addr*, int, Addr*);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
@@ -190,7 +158,6 @@ void maclin(void);
void macprag(void);
void macif(int);
void macend(void);
-void outhist(void);
void dodefine(char*);
void prfile(int32);
void linehist(char*, int);
@@ -199,3 +166,4 @@ void yyerror(char*, ...);
int yyparse(void);
void setinclude(char*);
int assemble(char*);
+void listinit(void);
diff --git a/src/cmd/5a/a.y b/src/cmd/5a/a.y
index c506ff9d5..56d0c563d 100644
--- a/src/cmd/5a/a.y
+++ b/src/cmd/5a/a.y
@@ -41,7 +41,7 @@
int32 lval;
double dval;
char sval[8];
- Gen gen;
+ Addr addr;
}
%left '|'
%left '^'
@@ -62,8 +62,8 @@
%token <sym> LNAME LLAB LVAR
%type <lval> con expr oexpr pointer offset sreg spreg creg
%type <lval> rcon cond reglist
-%type <gen> gen rel reg regreg freg shift fcon frcon
-%type <gen> imm ximm name oreg ireg nireg ioreg imsr
+%type <addr> gen rel reg regreg freg shift fcon frcon
+%type <addr> imm ximm name oreg ireg nireg ioreg imsr
%%
prog:
| prog
@@ -175,7 +175,7 @@ inst:
*/
| LTYPE8 cond ioreg ',' '[' reglist ']'
{
- Gen g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
@@ -184,7 +184,7 @@ inst:
}
| LTYPE8 cond '[' reglist ']' ',' ioreg
{
- Gen g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
@@ -279,7 +279,7 @@ inst:
*/
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
{
- Gen g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
@@ -294,7 +294,7 @@ inst:
(($11 & 15) << 0) | /* Crm */
(($12 & 7) << 5) | /* coprocessor information */
(1<<4); /* must be set */
- outcode(AWORD, Always, &nullgen, NREG, &g);
+ outcode(AMRC, Always, &nullgen, NREG, &g);
}
/*
* MULL r1,r2,(hi,lo)
@@ -336,7 +336,7 @@ inst:
{
if($2.type != D_CONST)
yyerror("index for FUNCDATA must be integer constant");
- if($4.type != D_EXTERN && $4.type != D_STATIC)
+ if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
yyerror("value for FUNCDATA must be symbol reference");
outcode($1, Always, &$2, NREG, &$4);
}
@@ -377,14 +377,12 @@ rel:
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
- $$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
- $$.sym = $1;
$$.offset = $1->value + $2;
}
@@ -408,7 +406,7 @@ ximm: '$' con
{
$$ = nullgen;
$$.type = D_SCONST;
- memcpy($$.sval, $2, sizeof($$.sval));
+ memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| fcon
@@ -417,13 +415,13 @@ fcon:
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = $2;
+ $$.u.dval = $2;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = -$3;
+ $$.u.dval = -$3;
}
reglist:
@@ -635,7 +633,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = $3;
- $$.sym = S;
+ $$.sym = nil;
$$.offset = $1;
}
| LNAME offset '(' pointer ')'
@@ -643,7 +641,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = $4;
- $$.sym = $1;
+ $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
@@ -651,7 +649,7 @@ name:
$$ = nullgen;
$$.type = D_OREG;
$$.name = D_STATIC;
- $$.sym = $1;
+ $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}
diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c
index c1b54e50b..571fdf7f2 100644
--- a/src/cmd/5a/lex.c
+++ b/src/cmd/5a/lex.c
@@ -51,60 +51,76 @@ systemtype(int sys)
#endif
}
+int
+Lconv(Fmt *fp)
+{
+ return linklinefmt(ctxt, fp);
+}
+
+void
+dodef(char *p)
+{
+ if(nDlist%8 == 0)
+ Dlist = allocn(Dlist, nDlist*sizeof(char *),
+ 8*sizeof(char *));
+ Dlist[nDlist++] = p;
+}
+
+void
+usage(void)
+{
+ print("usage: %ca [options] file.c...\n", thechar);
+ flagprint(1);
+ errorexit();
+}
+
void
main(int argc, char *argv[])
{
char *p;
- int c;
thechar = '5';
thestring = "arm";
+ ctxt = linknew(&linkarm);
+ ctxt->diag = yyerror;
+ ctxt->bso = &bstdout;
+ Binit(&bstdout, 1, OWRITE);
+ listinit5();
+ fmtinstall('L', Lconv);
+
+ // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+ // but not other values.
+ p = getgoarch();
+ if(strncmp(p, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
+
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
cinit();
outfile = 0;
setinclude(".");
- ARGBEGIN {
- default:
- c = ARGC();
- if(c >= 0 && c < sizeof(debug))
- debug[c] = 1;
- break;
-
- case 'o':
- outfile = ARGF();
- break;
-
- case 'D':
- p = ARGF();
- if(p) {
- if (nDlist%8 == 0)
- Dlist = allocn(Dlist, nDlist*sizeof(char *),
- 8*sizeof(char *));
- Dlist[nDlist++] = p;
- }
- break;
-
- case 'I':
- p = ARGF();
- setinclude(p);
- break;
- case 't':
- thechar = 't';
- thestring = "thumb";
- break;
- } ARGEND
- if(*argv == 0) {
- print("usage: %ca [-options] file.s\n", thechar);
- errorexit();
- }
+
+ flagfn1("D", "name[=value]: add #define", dodef);
+ flagfn1("I", "dir: add dir to include path", setinclude);
+ flagcount("S", "print assembly and machine code", &debug['S']);
+ flagcount("m", "debug preprocessor macros", &debug['m']);
+ flagstr("o", "file: set output file", &outfile);
+ flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
+
+ flagparse(&argc, &argv, usage);
+ ctxt->debugasm = debug['S'];
+
+ if(argc < 1)
+ usage();
if(argc > 1){
print("can't assemble multiple files\n");
errorexit();
}
+
if(assemble(argv[0]))
errorexit();
+ Bflush(&bstdout);
exits(0);
}
@@ -143,30 +159,22 @@ assemble(char *file)
errorexit();
}
Binit(&obuf, of, OWRITE);
-
- pass = 1;
- pinit(file);
-
- Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
-
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- if(nerrors) {
+ Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
+ Bprint(&obuf, "!\n");
+
+ for(pass = 1; pass <= 2; pass++) {
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
cclean();
- return nerrors;
+ if(nerrors)
+ return nerrors;
}
- Bprint(&obuf, "\n!\n");
-
- pass = 2;
- outhist();
- pinit(file);
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- cclean();
- return nerrors;
+ writeobj(ctxt, &obuf);
+ Bflush(&obuf);
+ return 0;
}
struct
@@ -426,15 +434,9 @@ cinit(void)
Sym *s;
int i;
- nullgen.sym = S;
- nullgen.offset = 0;
nullgen.type = D_NONE;
nullgen.name = D_NONE;
nullgen.reg = NREG;
- if(FPCHIP)
- nullgen.dval = 0;
- for(i=0; i<sizeof(nullgen.sval); i++)
- nullgen.sval[i] = 0;
nerrors = 0;
iostack = I;
@@ -448,13 +450,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
-
- pathname = allocn(pathname, 0, 100);
- if(getwd(pathname, 99) == 0) {
- pathname = allocn(pathname, 100, 900);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
- }
}
void
@@ -466,7 +461,7 @@ syminit(Sym *s)
}
int
-isreg(Gen *g)
+isreg(Addr *g)
{
USED(g);
@@ -476,81 +471,7 @@ isreg(Gen *g)
void
cclean(void)
{
-
outcode(AEND, Always, &nullgen, NREG, &nullgen);
- Bflush(&obuf);
-}
-
-void
-zname(char *n, int t, int s)
-{
-
- BPUTC(&obuf, ANAME);
- BPUTC(&obuf, t); /* type */
- BPUTC(&obuf, s); /* sym */
- while(*n) {
- BPUTC(&obuf, *n);
- n++;
- }
- BPUTC(&obuf, 0);
-}
-
-void
-zaddr(Gen *a, int s)
-{
- int32 l;
- int i;
- char *n;
- Ieee e;
-
- BPUTC(&obuf, a->type);
- BPUTC(&obuf, a->reg);
- BPUTC(&obuf, s);
- BPUTC(&obuf, a->name);
- BPUTC(&obuf, 0);
- switch(a->type) {
- default:
- print("unknown type %d\n", a->type);
- exits("arg");
-
- case D_NONE:
- case D_REG:
- case D_FREG:
- case D_PSR:
- case D_FPCR:
- break;
-
- case D_REGREG:
- case D_REGREG2:
- BPUTC(&obuf, a->offset);
- break;
-
- case D_CONST2:
- l = a->offset2;
- BPUTLE4(&obuf, l);
- // fall through
- case D_OREG:
- case D_CONST:
- case D_BRANCH:
- case D_SHIFT:
- l = a->offset;
- BPUTLE4(&obuf, l);
- break;
-
- case D_SCONST:
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(&obuf, *n);
- n++;
- }
- break;
-
- case D_FCONST:
- ieeedtod(&e, a->dval);
- BPUTLE4(&obuf, e.l);
- BPUTLE4(&obuf, e.h);
- break;
- }
}
static int bcode[] =
@@ -573,11 +494,13 @@ static int bcode[] =
ANOP,
};
+static Prog *lastpc;
+
void
-outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
+outcode(int a, int scond, Addr *g1, int reg, Addr *g2)
{
- int sf, st, t;
- Sym *s;
+ Prog *p;
+ Plist *pl;
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
if(a == AB){
@@ -587,154 +510,28 @@ outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
if(pass == 1)
goto out;
-jackpot:
- sf = 0;
- s = g1->sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = g1->name;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = g2->sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = g2->name;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- BPUTC(&obuf, a);
- BPUTC(&obuf, scond);
- BPUTC(&obuf, reg);
- BPUTLE4(&obuf, stmtline);
- zaddr(g1, sf);
- zaddr(g2, st);
+
+ p = malloc(sizeof *p);
+ memset(p, 0, sizeof *p);
+ p->as = a;
+ p->lineno = stmtline;
+ p->scond = scond;
+ p->from = *g1;
+ p->reg = reg;
+ p->to = *g2;
+ p->pc = pc;
+
+ if(lastpc == nil) {
+ pl = linknewplist(ctxt);
+ pl->firstpc = p;
+ } else
+ lastpc->link = p;
+ lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
-void
-outhist(void)
-{
- Gen g;
- Hist *h;
- char *p, *q, *op, c;
- int n;
- char *tofree;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
- g = nullgen;
- c = '/';
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p != nil && goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- op = 0;
- if(systemtype(Windows) && p && p[1] == ':'){
- c = p[2];
- } else if(p && p[0] != c && h->offset == 0 && pathname){
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname;
- c = p[2];
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = strchr(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- BPUTC(&obuf, ANAME);
- BPUTC(&obuf, D_FILE); /* type */
- BPUTC(&obuf, 1); /* sym */
- BPUTC(&obuf, '<');
- Bwrite(&obuf, p, n);
- BPUTC(&obuf, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- g.offset = h->offset;
-
- BPUTC(&obuf, AHISTORY);
- BPUTC(&obuf, Always);
- BPUTC(&obuf, 0);
- BPUTLE4(&obuf, h->line);
- zaddr(&nullgen, 0);
- zaddr(&g, 0);
-
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
#include "../cc/lexbody"
#include "../cc/macbody"
diff --git a/src/cmd/5a/y.tab.c b/src/cmd/5a/y.tab.c
index dd102a09a..0bc8c34e1 100644
--- a/src/cmd/5a/y.tab.c
+++ b/src/cmd/5a/y.tab.c
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.7.12-4996"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -58,14 +58,11 @@
/* Pull parsers. */
#define YYPULL 1
-/* Using locations. */
-#define YYLSP_NEEDED 0
/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
+/* Line 371 of yacc.c */
#line 31 "a.y"
#include <u.h>
@@ -74,14 +71,16 @@
#include "a.h"
#include "../../pkg/runtime/funcdata.h"
+/* Line 371 of yacc.c */
+#line 76 "y.tab.c"
-/* Line 268 of yacc.c */
-#line 80 "y.tab.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULL
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULL nullptr
+# else
+# define YY_NULL 0
+# endif
+# endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
@@ -91,11 +90,17 @@
# define YYERROR_VERBOSE 0
#endif
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+ by #include "y.tab.h". */
+#ifndef YY_YY_Y_TAB_H_INCLUDED
+# define YY_YY_Y_TAB_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
#endif
-
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -205,36 +210,49 @@
-
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
-
-/* Line 293 of yacc.c */
+/* Line 387 of yacc.c */
#line 39 "a.y"
Sym *sym;
int32 lval;
double dval;
char sval[8];
- Gen gen;
+ Addr addr;
-
-/* Line 293 of yacc.c */
-#line 226 "y.tab.c"
+/* Line 387 of yacc.c */
+#line 228 "y.tab.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
+extern YYSTYPE yylval;
-/* Copy the second part of user declarations. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_YY_Y_TAB_H_INCLUDED */
+/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 238 "y.tab.c"
+/* Line 390 of yacc.c */
+#line 256 "y.tab.c"
#ifdef short
# undef short
@@ -287,24 +305,33 @@ typedef short int yytype_int16;
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
-# define YY_(msgid) msgid
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+ || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+# define __attribute__(Spec) /* empty */
# endif
#endif
/* Suppress unused-variable warnings by "using" E. */
#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
#else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
#endif
+
/* Identity function, used to suppress warnings about constant conditions. */
#ifndef lint
-# define YYID(n) (n)
+# define YYID(N) (N)
#else
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
@@ -340,6 +367,7 @@ YYID (yyi)
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
@@ -431,20 +459,20 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
+/* Copy COUNT objects from SRC to DST. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
while (YYID (0))
# endif
# endif
@@ -594,19 +622,19 @@ static const yytype_uint16 yyrline[] =
141, 148, 155, 162, 169, 176, 185, 197, 201, 205,
212, 219, 225, 231, 240, 247, 254, 261, 265, 269,
273, 280, 302, 310, 319, 326, 335, 346, 352, 355,
- 359, 364, 365, 368, 374, 383, 391, 397, 402, 407,
- 413, 416, 422, 430, 434, 443, 449, 450, 451, 452,
- 457, 463, 469, 475, 476, 479, 480, 488, 497, 498,
- 507, 508, 514, 517, 518, 519, 521, 529, 537, 546,
- 552, 558, 564, 572, 578, 586, 587, 591, 599, 600,
- 606, 607, 615, 616, 619, 625, 633, 641, 649, 659,
- 662, 666, 672, 673, 674, 677, 678, 682, 686, 690,
- 694, 700, 703, 709, 710, 714, 718, 722, 726, 730,
- 734, 738, 742, 746
+ 359, 364, 365, 368, 374, 382, 389, 395, 400, 405,
+ 411, 414, 420, 428, 432, 441, 447, 448, 449, 450,
+ 455, 461, 467, 473, 474, 477, 478, 486, 495, 496,
+ 505, 506, 512, 515, 516, 517, 519, 527, 535, 544,
+ 550, 556, 562, 570, 576, 584, 585, 589, 597, 598,
+ 604, 605, 613, 614, 617, 623, 631, 639, 647, 657,
+ 660, 664, 670, 671, 672, 675, 676, 680, 684, 688,
+ 692, 698, 701, 707, 708, 712, 716, 720, 724, 728,
+ 732, 736, 740, 744
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@@ -623,7 +651,7 @@ static const char *const yytname[] =
"$@1", "line", "$@2", "$@3", "inst", "cond", "comma", "rel", "ximm",
"fcon", "reglist", "gen", "nireg", "ireg", "ioreg", "oreg", "imsr",
"imm", "reg", "regreg", "shift", "rcon", "sreg", "spreg", "creg",
- "frcon", "freg", "name", "offset", "pointer", "con", "oexpr", "expr", 0
+ "frcon", "freg", "name", "offset", "pointer", "con", "oexpr", "expr", YY_NULL
};
#endif
@@ -850,10 +878,10 @@ static const yytype_int16 yytable[] =
202, 203, 204, 198, 199, 200, 201, 202, 203, 204
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-128))
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-128)))
-#define yytable_value_is_error(yytable_value) \
+#define yytable_value_is_error(Yytable_value) \
YYID (0)
static const yytype_int16 yycheck[] =
@@ -988,62 +1016,35 @@ static const yytype_uint8 yystos[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (YYID (0))
-
+/* Error token number */
#define YYTERROR 1
#define YYERRCODE 256
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
- while (YYID (0))
-#endif
-
-
/* This macro is provided for backward compatibility. */
-
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
/* YYLEX -- calling `yylex' with the right arguments. */
-
#ifdef YYLEX_PARAM
# define YYLEX yylex (YYLEX_PARAM)
#else
@@ -1093,6 +1094,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
YYSTYPE const * const yyvaluep;
#endif
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
if (!yyvaluep)
return;
# ifdef YYPRINT
@@ -1101,11 +1104,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
# else
YYUSE (yyoutput);
# endif
- switch (yytype)
- {
- default:
- break;
- }
+ YYUSE (yytype);
}
@@ -1344,12 +1343,11 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
- const char *yyformat = 0;
+ const char *yyformat = YY_NULL;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1409,11 +1407,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
break;
}
yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
}
}
}
@@ -1433,10 +1433,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
# undef YYCASE_
}
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
if (*yymsg_alloc < yysize)
{
@@ -1492,36 +1494,26 @@ yydestruct (yymsg, yytype, yyvaluep)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
- switch (yytype)
- {
-
- default:
- break;
- }
+ YYUSE (yytype);
}
-/* Prevent warnings from -Wmissing-prototypes. */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
/* The lookahead symbol. */
int yychar;
+
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
/* The semantic value of the lookahead symbol. */
-YYSTYPE yylval;
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
/* Number of syntax errors so far. */
int yynerrs;
@@ -1561,7 +1553,7 @@ yyparse ()
`yyss': related to states.
`yyvs': related to semantic values.
- Refer to the stacks thru separate pointers, to allow yyoverflow
+ Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
@@ -1579,7 +1571,7 @@ yyparse ()
int yyn;
int yyresult;
/* Lookahead token as an internal (translated) token number. */
- int yytoken;
+ int yytoken = 0;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
@@ -1597,9 +1589,8 @@ yyparse ()
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1608,14 +1599,6 @@ yyparse ()
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
- yyssp = yyss;
- yyvsp = yyvs;
-
goto yysetstate;
/*------------------------------------------------------------.
@@ -1756,7 +1739,9 @@ yybackup:
yychar = YYEMPTY;
yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
goto yynewstate;
@@ -1793,8 +1778,7 @@ yyreduce:
switch (yyn)
{
case 3:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 70 "a.y"
{
stmtline = lineno;
@@ -1802,8 +1786,7 @@ yyreduce:
break;
case 5:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 77 "a.y"
{
if((yyvsp[(1) - (2)].sym)->value != pc)
@@ -1813,8 +1796,7 @@ yyreduce:
break;
case 7:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 84 "a.y"
{
(yyvsp[(1) - (2)].sym)->type = LLAB;
@@ -1823,8 +1805,7 @@ yyreduce:
break;
case 9:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 90 "a.y"
{
(yyvsp[(1) - (4)].sym)->type = LVAR;
@@ -1833,8 +1814,7 @@ yyreduce:
break;
case 10:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 95 "a.y"
{
if((yyvsp[(1) - (4)].sym)->value != (yyvsp[(3) - (4)].lval))
@@ -1844,162 +1824,145 @@ yyreduce:
break;
case 14:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 109 "a.y"
{
- outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].gen), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].gen));
+ outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].addr));
}
break;
case 15:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 113 "a.y"
{
- outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].gen), (yyvsp[(5) - (6)].lval), &nullgen);
+ outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].lval), &nullgen);
}
break;
case 16:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 117 "a.y"
{
- outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].gen), NREG, &(yyvsp[(5) - (5)].gen));
+ outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
}
break;
case 17:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 124 "a.y"
{
- outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].gen), NREG, &(yyvsp[(5) - (5)].gen));
+ outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
}
break;
case 18:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 131 "a.y"
{
- outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].gen), NREG, &(yyvsp[(5) - (5)].gen));
+ outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
}
break;
case 19:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 138 "a.y"
{
- outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].gen));
+ outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
}
break;
case 20:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 142 "a.y"
{
- outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].gen));
+ outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
}
break;
case 21:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 149 "a.y"
{
- outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].gen));
+ outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
}
break;
case 22:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 156 "a.y"
{
- outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].gen));
+ outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
}
break;
case 23:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 163 "a.y"
{
- outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].gen));
+ outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
}
break;
case 24:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 170 "a.y"
{
- outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].gen), (yyvsp[(5) - (6)].lval), &nullgen);
+ outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].lval), &nullgen);
}
break;
case 25:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 177 "a.y"
{
- Gen g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
g.offset = (yyvsp[(6) - (7)].lval);
- outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].gen), NREG, &g);
+ outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), NREG, &g);
}
break;
case 26:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 186 "a.y"
{
- Gen g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
g.offset = (yyvsp[(4) - (7)].lval);
- outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, NREG, &(yyvsp[(7) - (7)].gen));
+ outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, NREG, &(yyvsp[(7) - (7)].addr));
}
break;
case 27:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 198 "a.y"
{
- outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(5) - (7)].gen), (yyvsp[(3) - (7)].gen).reg, &(yyvsp[(7) - (7)].gen));
+ outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(5) - (7)].addr), (yyvsp[(3) - (7)].addr).reg, &(yyvsp[(7) - (7)].addr));
}
break;
case 28:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 202 "a.y"
{
- outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(5) - (6)].gen), (yyvsp[(3) - (6)].gen).reg, &(yyvsp[(3) - (6)].gen));
+ outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(5) - (6)].addr), (yyvsp[(3) - (6)].addr).reg, &(yyvsp[(3) - (6)].addr));
}
break;
case 29:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 206 "a.y"
{
- outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(4) - (6)].gen), (yyvsp[(6) - (6)].gen).reg, &(yyvsp[(6) - (6)].gen));
+ outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(4) - (6)].addr), (yyvsp[(6) - (6)].addr).reg, &(yyvsp[(6) - (6)].addr));
}
break;
case 30:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 213 "a.y"
{
outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, NREG, &nullgen);
@@ -2007,107 +1970,96 @@ yyreduce:
break;
case 31:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 220 "a.y"
{
- (yyvsp[(4) - (4)].gen).type = D_CONST2;
- (yyvsp[(4) - (4)].gen).offset2 = ArgsSizeUnknown;
- outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].gen), 0, &(yyvsp[(4) - (4)].gen));
+ (yyvsp[(4) - (4)].addr).type = D_CONST2;
+ (yyvsp[(4) - (4)].addr).offset2 = ArgsSizeUnknown;
+ outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
}
break;
case 32:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 226 "a.y"
{
- (yyvsp[(6) - (6)].gen).type = D_CONST2;
- (yyvsp[(6) - (6)].gen).offset2 = ArgsSizeUnknown;
- outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].gen), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].gen));
+ (yyvsp[(6) - (6)].addr).type = D_CONST2;
+ (yyvsp[(6) - (6)].addr).offset2 = ArgsSizeUnknown;
+ outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
}
break;
case 33:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 232 "a.y"
{
- (yyvsp[(6) - (8)].gen).type = D_CONST2;
- (yyvsp[(6) - (8)].gen).offset2 = (yyvsp[(8) - (8)].lval);
- outcode((yyvsp[(1) - (8)].lval), Always, &(yyvsp[(2) - (8)].gen), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].gen));
+ (yyvsp[(6) - (8)].addr).type = D_CONST2;
+ (yyvsp[(6) - (8)].addr).offset2 = (yyvsp[(8) - (8)].lval);
+ outcode((yyvsp[(1) - (8)].lval), Always, &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].addr));
}
break;
case 34:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 241 "a.y"
{
- outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].gen), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].gen));
+ outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
}
break;
case 35:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 248 "a.y"
{
- outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].gen), NREG, &nullgen);
+ outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), NREG, &nullgen);
}
break;
case 36:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 255 "a.y"
{
- outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].gen));
+ outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
}
break;
case 37:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 262 "a.y"
{
- outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].gen), NREG, &(yyvsp[(5) - (5)].gen));
+ outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
}
break;
case 38:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 266 "a.y"
{
- outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].gen), NREG, &(yyvsp[(5) - (5)].gen));
+ outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
}
break;
case 39:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 270 "a.y"
{
- outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].gen), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].gen));
+ outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].lval), &(yyvsp[(7) - (7)].addr));
}
break;
case 40:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 274 "a.y"
{
- outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].gen), (yyvsp[(5) - (6)].gen).reg, &nullgen);
+ outcode((yyvsp[(1) - (6)].lval), (yyvsp[(2) - (6)].lval), &(yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr).reg, &nullgen);
}
break;
case 41:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 281 "a.y"
{
- Gen g;
+ Addr g;
g = nullgen;
g.type = D_CONST;
@@ -2122,66 +2074,60 @@ yyreduce:
(((yyvsp[(11) - (12)].lval) & 15) << 0) | /* Crm */
(((yyvsp[(12) - (12)].lval) & 7) << 5) | /* coprocessor information */
(1<<4); /* must be set */
- outcode(AWORD, Always, &nullgen, NREG, &g);
+ outcode(AMRC, Always, &nullgen, NREG, &g);
}
break;
case 42:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 303 "a.y"
{
- outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].gen), (yyvsp[(5) - (7)].gen).reg, &(yyvsp[(7) - (7)].gen));
+ outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), (yyvsp[(5) - (7)].addr).reg, &(yyvsp[(7) - (7)].addr));
}
break;
case 43:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 311 "a.y"
{
- (yyvsp[(7) - (9)].gen).type = D_REGREG2;
- (yyvsp[(7) - (9)].gen).offset = (yyvsp[(9) - (9)].lval);
- outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].gen), (yyvsp[(5) - (9)].gen).reg, &(yyvsp[(7) - (9)].gen));
+ (yyvsp[(7) - (9)].addr).type = D_REGREG2;
+ (yyvsp[(7) - (9)].addr).offset = (yyvsp[(9) - (9)].lval);
+ outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].addr), (yyvsp[(5) - (9)].addr).reg, &(yyvsp[(7) - (9)].addr));
}
break;
case 44:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 320 "a.y"
{
- outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].gen), NREG, &nullgen);
+ outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), NREG, &nullgen);
}
break;
case 45:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 327 "a.y"
{
- if((yyvsp[(2) - (4)].gen).type != D_CONST || (yyvsp[(4) - (4)].gen).type != D_CONST)
+ if((yyvsp[(2) - (4)].addr).type != D_CONST || (yyvsp[(4) - (4)].addr).type != D_CONST)
yyerror("arguments to PCDATA must be integer constants");
- outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].gen), NREG, &(yyvsp[(4) - (4)].gen));
+ outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
}
break;
case 46:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 336 "a.y"
{
- if((yyvsp[(2) - (4)].gen).type != D_CONST)
+ if((yyvsp[(2) - (4)].addr).type != D_CONST)
yyerror("index for FUNCDATA must be integer constant");
- if((yyvsp[(4) - (4)].gen).type != D_EXTERN && (yyvsp[(4) - (4)].gen).type != D_STATIC)
+ if((yyvsp[(4) - (4)].addr).type != D_EXTERN && (yyvsp[(4) - (4)].addr).type != D_STATIC && (yyvsp[(4) - (4)].addr).type != D_OREG)
yyerror("value for FUNCDATA must be symbol reference");
- outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].gen), NREG, &(yyvsp[(4) - (4)].gen));
+ outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
}
break;
case 47:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 347 "a.y"
{
outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, NREG, &nullgen);
@@ -2189,8 +2135,7 @@ yyreduce:
break;
case 48:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 352 "a.y"
{
(yyval.lval) = Always;
@@ -2198,8 +2143,7 @@ yyreduce:
break;
case 49:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 356 "a.y"
{
(yyval.lval) = ((yyvsp[(1) - (2)].lval) & ~C_SCOND) | (yyvsp[(2) - (2)].lval);
@@ -2207,8 +2151,7 @@ yyreduce:
break;
case 50:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 360 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (2)].lval) | (yyvsp[(2) - (2)].lval);
@@ -2216,119 +2159,106 @@ yyreduce:
break;
case 53:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 369 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) + pc;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
}
break;
case 54:
-
-/* Line 1806 of yacc.c */
+/* Line 1787 of yacc.c */
#line 375 "a.y"
{
- (yyval.gen) = nullgen;
+ (yyval.addr) = nullgen;
if(pass == 2)
yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->name);
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).sym = (yyvsp[(1) - (2)].sym);
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 55:
-
-/* Line 1806 of yacc.c */
-#line 384 "a.y"
+/* Line 1787 of yacc.c */
+#line 383 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).sym = (yyvsp[(1) - (2)].sym);
- (yyval.gen).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
}
break;
case 56:
-
-/* Line 1806 of yacc.c */
-#line 392 "a.y"
+/* Line 1787 of yacc.c */
+#line 390 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_CONST;
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_CONST;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 57:
-
-/* Line 1806 of yacc.c */
-#line 398 "a.y"
+/* Line 1787 of yacc.c */
+#line 396 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
- (yyval.gen).type = D_CONST;
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
+ (yyval.addr).type = D_CONST;
}
break;
case 58:
-
-/* Line 1806 of yacc.c */
-#line 403 "a.y"
+/* Line 1787 of yacc.c */
+#line 401 "a.y"
{
- (yyval.gen) = (yyvsp[(4) - (4)].gen);
- (yyval.gen).type = D_OCONST;
+ (yyval.addr) = (yyvsp[(4) - (4)].addr);
+ (yyval.addr).type = D_OCONST;
}
break;
case 59:
-
-/* Line 1806 of yacc.c */
-#line 408 "a.y"
+/* Line 1787 of yacc.c */
+#line 406 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SCONST;
- memcpy((yyval.gen).sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.gen).sval));
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SCONST;
+ memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
}
break;
case 61:
-
-/* Line 1806 of yacc.c */
-#line 417 "a.y"
+/* Line 1787 of yacc.c */
+#line 415 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = (yyvsp[(2) - (2)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
}
break;
case 62:
-
-/* Line 1806 of yacc.c */
-#line 423 "a.y"
+/* Line 1787 of yacc.c */
+#line 421 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = -(yyvsp[(3) - (3)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
}
break;
case 63:
-
-/* Line 1806 of yacc.c */
-#line 431 "a.y"
+/* Line 1787 of yacc.c */
+#line 429 "a.y"
{
(yyval.lval) = 1 << (yyvsp[(1) - (1)].lval);
}
break;
case 64:
-
-/* Line 1806 of yacc.c */
-#line 435 "a.y"
+/* Line 1787 of yacc.c */
+#line 433 "a.y"
{
int i;
(yyval.lval)=0;
@@ -2340,185 +2270,168 @@ yyreduce:
break;
case 65:
-
-/* Line 1806 of yacc.c */
-#line 444 "a.y"
+/* Line 1787 of yacc.c */
+#line 442 "a.y"
{
(yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval);
}
break;
case 69:
-
-/* Line 1806 of yacc.c */
-#line 453 "a.y"
+/* Line 1787 of yacc.c */
+#line 451 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (4)].gen);
- (yyval.gen).reg = (yyvsp[(3) - (4)].lval);
+ (yyval.addr) = (yyvsp[(1) - (4)].addr);
+ (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
}
break;
case 70:
-
-/* Line 1806 of yacc.c */
-#line 458 "a.y"
+/* Line 1787 of yacc.c */
+#line 456 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_PSR;
- (yyval.gen).reg = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_PSR;
+ (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 71:
-
-/* Line 1806 of yacc.c */
-#line 464 "a.y"
+/* Line 1787 of yacc.c */
+#line 462 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FPCR;
- (yyval.gen).reg = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FPCR;
+ (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 72:
-
-/* Line 1806 of yacc.c */
-#line 470 "a.y"
+/* Line 1787 of yacc.c */
+#line 468 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_OREG;
- (yyval.gen).offset = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
}
break;
case 76:
-
-/* Line 1806 of yacc.c */
-#line 481 "a.y"
+/* Line 1787 of yacc.c */
+#line 479 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (1)].gen);
- if((yyvsp[(1) - (1)].gen).name != D_EXTERN && (yyvsp[(1) - (1)].gen).name != D_STATIC) {
+ (yyval.addr) = (yyvsp[(1) - (1)].addr);
+ if((yyvsp[(1) - (1)].addr).name != D_EXTERN && (yyvsp[(1) - (1)].addr).name != D_STATIC) {
}
}
break;
case 77:
-
-/* Line 1806 of yacc.c */
-#line 489 "a.y"
+/* Line 1787 of yacc.c */
+#line 487 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_OREG;
- (yyval.gen).reg = (yyvsp[(2) - (3)].lval);
- (yyval.gen).offset = 0;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).reg = (yyvsp[(2) - (3)].lval);
+ (yyval.addr).offset = 0;
}
break;
case 79:
-
-/* Line 1806 of yacc.c */
-#line 499 "a.y"
+/* Line 1787 of yacc.c */
+#line 497 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_OREG;
- (yyval.gen).reg = (yyvsp[(3) - (4)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 81:
-
-/* Line 1806 of yacc.c */
-#line 509 "a.y"
+/* Line 1787 of yacc.c */
+#line 507 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (4)].gen);
- (yyval.gen).type = D_OREG;
- (yyval.gen).reg = (yyvsp[(3) - (4)].lval);
+ (yyval.addr) = (yyvsp[(1) - (4)].addr);
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
}
break;
case 86:
-
-/* Line 1806 of yacc.c */
-#line 522 "a.y"
+/* Line 1787 of yacc.c */
+#line 520 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_CONST;
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_CONST;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 87:
-
-/* Line 1806 of yacc.c */
-#line 530 "a.y"
+/* Line 1787 of yacc.c */
+#line 528 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_REG;
- (yyval.gen).reg = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_REG;
+ (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 88:
-
-/* Line 1806 of yacc.c */
-#line 538 "a.y"
+/* Line 1787 of yacc.c */
+#line 536 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_REGREG;
- (yyval.gen).reg = (yyvsp[(2) - (5)].lval);
- (yyval.gen).offset = (yyvsp[(4) - (5)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_REGREG;
+ (yyval.addr).reg = (yyvsp[(2) - (5)].lval);
+ (yyval.addr).offset = (yyvsp[(4) - (5)].lval);
}
break;
case 89:
-
-/* Line 1806 of yacc.c */
-#line 547 "a.y"
+/* Line 1787 of yacc.c */
+#line 545 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SHIFT;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (0 << 5);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SHIFT;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (0 << 5);
}
break;
case 90:
-
-/* Line 1806 of yacc.c */
-#line 553 "a.y"
+/* Line 1787 of yacc.c */
+#line 551 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SHIFT;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (1 << 5);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SHIFT;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (1 << 5);
}
break;
case 91:
-
-/* Line 1806 of yacc.c */
-#line 559 "a.y"
+/* Line 1787 of yacc.c */
+#line 557 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SHIFT;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (2 << 5);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SHIFT;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (2 << 5);
}
break;
case 92:
-
-/* Line 1806 of yacc.c */
-#line 565 "a.y"
+/* Line 1787 of yacc.c */
+#line 563 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SHIFT;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (3 << 5);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SHIFT;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (3 << 5);
}
break;
case 93:
-
-/* Line 1806 of yacc.c */
-#line 573 "a.y"
+/* Line 1787 of yacc.c */
+#line 571 "a.y"
{
if((yyval.lval) < 0 || (yyval.lval) >= 16)
print("register value out of range\n");
@@ -2527,9 +2440,8 @@ yyreduce:
break;
case 94:
-
-/* Line 1806 of yacc.c */
-#line 579 "a.y"
+/* Line 1787 of yacc.c */
+#line 577 "a.y"
{
if((yyval.lval) < 0 || (yyval.lval) >= 32)
print("shift value out of range\n");
@@ -2538,18 +2450,16 @@ yyreduce:
break;
case 96:
-
-/* Line 1806 of yacc.c */
-#line 588 "a.y"
+/* Line 1787 of yacc.c */
+#line 586 "a.y"
{
(yyval.lval) = REGPC;
}
break;
case 97:
-
-/* Line 1806 of yacc.c */
-#line 592 "a.y"
+/* Line 1787 of yacc.c */
+#line 590 "a.y"
{
if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
print("register value out of range\n");
@@ -2558,18 +2468,16 @@ yyreduce:
break;
case 99:
-
-/* Line 1806 of yacc.c */
-#line 601 "a.y"
+/* Line 1787 of yacc.c */
+#line 599 "a.y"
{
(yyval.lval) = REGSP;
}
break;
case 101:
-
-/* Line 1806 of yacc.c */
-#line 608 "a.y"
+/* Line 1787 of yacc.c */
+#line 606 "a.y"
{
if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
print("register value out of range\n");
@@ -2578,250 +2486,224 @@ yyreduce:
break;
case 104:
-
-/* Line 1806 of yacc.c */
-#line 620 "a.y"
+/* Line 1787 of yacc.c */
+#line 618 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FREG;
- (yyval.gen).reg = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FREG;
+ (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
}
break;
case 105:
-
-/* Line 1806 of yacc.c */
-#line 626 "a.y"
+/* Line 1787 of yacc.c */
+#line 624 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FREG;
- (yyval.gen).reg = (yyvsp[(3) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FREG;
+ (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
}
break;
case 106:
-
-/* Line 1806 of yacc.c */
-#line 634 "a.y"
+/* Line 1787 of yacc.c */
+#line 632 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_OREG;
- (yyval.gen).name = (yyvsp[(3) - (4)].lval);
- (yyval.gen).sym = S;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).name = (yyvsp[(3) - (4)].lval);
+ (yyval.addr).sym = nil;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 107:
-
-/* Line 1806 of yacc.c */
-#line 642 "a.y"
+/* Line 1787 of yacc.c */
+#line 640 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_OREG;
- (yyval.gen).name = (yyvsp[(4) - (5)].lval);
- (yyval.gen).sym = (yyvsp[(1) - (5)].sym);
- (yyval.gen).offset = (yyvsp[(2) - (5)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).name = (yyvsp[(4) - (5)].lval);
+ (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
+ (yyval.addr).offset = (yyvsp[(2) - (5)].lval);
}
break;
case 108:
-
-/* Line 1806 of yacc.c */
-#line 650 "a.y"
+/* Line 1787 of yacc.c */
+#line 648 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_OREG;
- (yyval.gen).name = D_STATIC;
- (yyval.gen).sym = (yyvsp[(1) - (7)].sym);
- (yyval.gen).offset = (yyvsp[(4) - (7)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_OREG;
+ (yyval.addr).name = D_STATIC;
+ (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
+ (yyval.addr).offset = (yyvsp[(4) - (7)].lval);
}
break;
case 109:
-
-/* Line 1806 of yacc.c */
-#line 659 "a.y"
+/* Line 1787 of yacc.c */
+#line 657 "a.y"
{
(yyval.lval) = 0;
}
break;
case 110:
-
-/* Line 1806 of yacc.c */
-#line 663 "a.y"
+/* Line 1787 of yacc.c */
+#line 661 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 111:
-
-/* Line 1806 of yacc.c */
-#line 667 "a.y"
+/* Line 1787 of yacc.c */
+#line 665 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 116:
-
-/* Line 1806 of yacc.c */
-#line 679 "a.y"
+/* Line 1787 of yacc.c */
+#line 677 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
}
break;
case 117:
-
-/* Line 1806 of yacc.c */
-#line 683 "a.y"
+/* Line 1787 of yacc.c */
+#line 681 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 118:
-
-/* Line 1806 of yacc.c */
-#line 687 "a.y"
+/* Line 1787 of yacc.c */
+#line 685 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 119:
-
-/* Line 1806 of yacc.c */
-#line 691 "a.y"
+/* Line 1787 of yacc.c */
+#line 689 "a.y"
{
(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
}
break;
case 120:
-
-/* Line 1806 of yacc.c */
-#line 695 "a.y"
+/* Line 1787 of yacc.c */
+#line 693 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (3)].lval);
}
break;
case 121:
-
-/* Line 1806 of yacc.c */
-#line 700 "a.y"
+/* Line 1787 of yacc.c */
+#line 698 "a.y"
{
(yyval.lval) = 0;
}
break;
case 122:
-
-/* Line 1806 of yacc.c */
-#line 704 "a.y"
+/* Line 1787 of yacc.c */
+#line 702 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 124:
-
-/* Line 1806 of yacc.c */
-#line 711 "a.y"
+/* Line 1787 of yacc.c */
+#line 709 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
}
break;
case 125:
-
-/* Line 1806 of yacc.c */
-#line 715 "a.y"
+/* Line 1787 of yacc.c */
+#line 713 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
}
break;
case 126:
-
-/* Line 1806 of yacc.c */
-#line 719 "a.y"
+/* Line 1787 of yacc.c */
+#line 717 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
}
break;
case 127:
-
-/* Line 1806 of yacc.c */
-#line 723 "a.y"
+/* Line 1787 of yacc.c */
+#line 721 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
}
break;
case 128:
-
-/* Line 1806 of yacc.c */
-#line 727 "a.y"
+/* Line 1787 of yacc.c */
+#line 725 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
}
break;
case 129:
-
-/* Line 1806 of yacc.c */
-#line 731 "a.y"
+/* Line 1787 of yacc.c */
+#line 729 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
}
break;
case 130:
-
-/* Line 1806 of yacc.c */
-#line 735 "a.y"
+/* Line 1787 of yacc.c */
+#line 733 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
}
break;
case 131:
-
-/* Line 1806 of yacc.c */
-#line 739 "a.y"
+/* Line 1787 of yacc.c */
+#line 737 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
}
break;
case 132:
-
-/* Line 1806 of yacc.c */
-#line 743 "a.y"
+/* Line 1787 of yacc.c */
+#line 741 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
}
break;
case 133:
-
-/* Line 1806 of yacc.c */
-#line 747 "a.y"
+/* Line 1787 of yacc.c */
+#line 745 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
}
break;
-
-/* Line 1806 of yacc.c */
-#line 2825 "y.tab.c"
+/* Line 1787 of yacc.c */
+#line 2707 "y.tab.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -2984,7 +2866,9 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
/* Shift the error token. */
@@ -3008,7 +2892,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -3050,4 +2934,3 @@ yyreturn:
}
-
diff --git a/src/cmd/5a/y.tab.h b/src/cmd/5a/y.tab.h
index 92230a2a5..f11fb85c6 100644
--- a/src/cmd/5a/y.tab.h
+++ b/src/cmd/5a/y.tab.h
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +30,15 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+#ifndef YY_YY_Y_TAB_H_INCLUDED
+# define YY_YY_Y_TAB_H_INCLUDED
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -139,24 +148,21 @@
-
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
-
-/* Line 2068 of yacc.c */
+/* Line 2053 of yacc.c */
#line 39 "a.y"
Sym *sym;
int32 lval;
double dval;
char sval[8];
- Gen gen;
+ Addr addr;
-
-/* Line 2068 of yacc.c */
-#line 160 "y.tab.h"
+/* Line 2053 of yacc.c */
+#line 166 "y.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -165,4 +171,18 @@ typedef union YYSTYPE
extern YYSTYPE yylval;
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+#endif /* !YY_YY_Y_TAB_H_INCLUDED */
diff --git a/src/cmd/5c/gc.h b/src/cmd/5c/gc.h
index 084da7e6a..40d3a2b07 100644
--- a/src/cmd/5c/gc.h
+++ b/src/cmd/5c/gc.h
@@ -46,46 +46,19 @@
#define SZ_DOUBLE 8
#define FNX 100
-typedef struct Adr Adr;
-typedef struct Prog Prog;
typedef struct Case Case;
typedef struct C1 C1;
typedef struct Multab Multab;
typedef struct Hintab Hintab;
-typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
#define R0ISZERO 0
-struct Adr
-{
- int32 offset;
- int32 offset2;
- double dval;
- char sval[NSNAME];
- Ieee ieee;
-
- Sym* sym;
- char type;
- uchar reg;
- char name;
- char etype;
-};
-#define A ((Adr*)0)
+#define A ((Addr*)0)
#define INDEXED 9
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* link;
- int32 lineno;
- char as;
- uchar reg;
- uchar scond;
-};
#define P ((Prog*)0)
struct Case
@@ -116,14 +89,6 @@ struct Hintab
char hint[10];
};
-struct Var
-{
- int32 offset;
- Sym* sym;
- char name;
- char etype;
-};
-
struct Reg
{
int32 pc;
@@ -174,7 +139,6 @@ EXTERN Node fconstnode;
EXTERN int32 continpc;
EXTERN int32 curarg;
EXTERN int32 cursafe;
-EXTERN Prog* firstp;
EXTERN int32 isbigendian;
EXTERN Prog* lastp;
EXTERN int32 maxargsafe;
@@ -230,7 +194,6 @@ EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
-EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
@@ -285,7 +248,7 @@ void regaalloc(Node*, Node*);
void regind(Node*, Node*);
void gprep(Node*, Node*);
void raddr(Node*, Prog*);
-void naddr(Node*, Adr*);
+void naddr(Node*, Addr*);
void gmovm(Node*, Node*, int);
void gmove(Node*, Node*);
void gmover(Node*, Node*);
@@ -314,19 +277,11 @@ int mulcon(Node*, Node*);
Multab* mulcon0(int32);
void nullwarn(Node*, Node*);
void outcode(void);
-void ieeedtod(Ieee*, double);
/*
* list
*/
void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Nconv(Fmt*);
-int Bconv(Fmt*);
-int Rconv(Fmt*);
/*
* reg.c
@@ -335,7 +290,7 @@ Reg* rega(void);
int rcmp(const void*, const void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
-Bits mkvar(Adr*, int);
+Bits mkvar(Addr*, int);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, int32);
void synch(Reg*, Bits);
@@ -343,7 +298,7 @@ uint32 allreg(uint32, Rgn*);
void paint1(Reg*, int);
uint32 paint2(Reg*, int);
void paint3(Reg*, int, int32, int);
-void addreg(Adr*, int);
+void addreg(Addr*, int);
/*
* peep.c
@@ -352,21 +307,21 @@ void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
-int regtyp(Adr*);
-int regzer(Adr*);
-int anyvar(Adr*);
+int regtyp(Addr*);
+int regzer(Addr*);
+int anyvar(Addr*);
int subprop(Reg*);
int copyprop(Reg*);
int shiftprop(Reg*);
-void constprop(Adr*, Adr*, Reg*);
-int copy1(Adr*, Adr*, Reg*, int);
-int copyu(Prog*, Adr*, Adr*);
+void constprop(Addr*, Addr*, Reg*);
+int copy1(Addr*, Addr*, Reg*, int);
+int copyu(Prog*, Addr*, Addr*);
-int copyas(Adr*, Adr*);
-int copyau(Adr*, Adr*);
-int copyau1(Prog*, Adr*);
-int copysub(Adr*, Adr*, Adr*, int);
-int copysub1(Prog*, Adr*, Adr*, int);
+int copyas(Addr*, Addr*);
+int copyau(Addr*, Addr*);
+int copyau1(Prog*, Addr*);
+int copysub(Addr*, Addr*, Addr*, int);
+int copysub1(Prog*, Addr*, Addr*, int);
int32 RtoB(int);
int32 FtoB(int);
@@ -377,11 +332,3 @@ void predicate(void);
int isbranch(Prog *);
int predicable(Prog *p);
int modifiescpsr(Prog *p);
-
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Adr*
-#pragma varargck type "N" Adr*
-#pragma varargck type "R" Adr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "S" char*
diff --git a/src/cmd/5c/list.c b/src/cmd/5c/list.c
index 30b88400f..98da424de 100644
--- a/src/cmd/5c/list.c
+++ b/src/cmd/5c/list.c
@@ -35,306 +35,5 @@
void
listinit(void)
{
-
- fmtinstall('A', Aconv);
- fmtinstall('P', Pconv);
- fmtinstall('S', Sconv);
- fmtinstall('N', Nconv);
- fmtinstall('B', Bconv);
- fmtinstall('D', Dconv);
- fmtinstall('R', Rconv);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == S) {
- sprint(ss, "$%d", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
-
-char *extra [] = {
- ".EQ", ".NE", ".CS", ".CC",
- ".MI", ".PL", ".VS", ".VC",
- ".HI", ".LS", ".GE", ".LT",
- ".GT", ".LE", "", ".NV",
-};
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ], sc[20];
- Prog *p;
- int a, s;
-
- p = va_arg(fp->args, Prog*);
- a = p->as;
- s = p->scond;
- strcpy(sc, extra[s & C_SCOND]);
- 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 == D_CONST)
- sprint(str, " %A%s %R,%D", a, sc, &p->from, &p->to);
- else
- if(p->to.type == D_CONST)
- sprint(str, " %A%s %D,%R", a, sc, &p->from, &p->to);
- else
- sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to);
- } else
- if(a == ADATA)
- sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
- else
- if(p->as == ATEXT)
- sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
- else
- if(p->reg == NREG)
- sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to);
- else
- if(p->from.type != D_FREG)
- sprint(str, " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
- else
- sprint(str, " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
- return fmtstrcpy(fp, str);
-}
-
-int
-Aconv(Fmt *fp)
-{
- char *s;
- int a;
-
- a = va_arg(fp->args, int);
- s = "???";
- if(a >= AXXX && a < ALAST)
- s = anames[a];
- return fmtstrcpy(fp, s);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Adr *a;
- const char *op;
- int v;
-
- a = va_arg(fp->args, Adr*);
- switch(a->type) {
-
- default:
- sprint(str, "GOK-type(%d)", a->type);
- break;
-
- case D_NONE:
- str[0] = 0;
- if(a->name != D_NONE || a->reg != NREG || a->sym != S)
- sprint(str, "%N(R%d)(NONE)", a, a->reg);
- break;
-
- case D_CONST:
- if(a->reg != NREG)
- sprint(str, "$%N(R%d)", a, a->reg);
- else
- sprint(str, "$%N", a);
- break;
-
- case D_CONST2:
- sprint(str, "$%d-%d", a->offset, a->offset2);
- break;
-
- case D_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 != NREG)
- sprint(str+strlen(str), "(R%d)", a->reg);
- break;
-
- case D_OREG:
- if(a->reg != NREG)
- sprint(str, "%N(R%d)", a, a->reg);
- else
- sprint(str, "%N", a);
- break;
-
- case D_REG:
- sprint(str, "R%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_FREG:
- sprint(str, "F%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_PSR:
- sprint(str, "PSR");
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%N(PSR)(REG)", a);
- break;
-
- case D_BRANCH:
- sprint(str, "%d(PC)", a->offset-pc);
- break;
-
- case D_FCONST:
- sprint(str, "$%.17e", a->dval);
- break;
-
- case D_SCONST:
- sprint(str, "$\"%S\"", a->sval);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Adr *a;
- int i, v;
-
- a = va_arg(fp->args, Adr*);
- sprint(str, "GOK-reglist");
- switch(a->type) {
- case D_CONST:
- case D_CONST2:
- if(a->reg != NREG)
- break;
- if(a->sym != S)
- 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);
-}
-
-int
-Sconv(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);
-}
-
-int
-Nconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Adr *a;
- Sym *s;
-
- a = va_arg(fp->args, Adr*);
- s = a->sym;
- if(s == S) {
- sprint(str, "%d", a->offset);
- goto out;
- }
- switch(a->name) {
- default:
- sprint(str, "GOK-name(%d)", a->name);
- break;
-
- case D_NONE:
- sprint(str, "%d", a->offset);
- break;
-
- case D_EXTERN:
- sprint(str, "%s+%d(SB)", s->name, a->offset);
- break;
-
- case D_STATIC:
- sprint(str, "%s<>+%d(SB)", s->name, a->offset);
- break;
-
- case D_AUTO:
- sprint(str, "%s-%d(SP)", s->name, -a->offset);
- break;
-
- case D_PARAM:
- sprint(str, "%s+%d(FP)", s->name, a->offset);
- break;
- }
-out:
- return fmtstrcpy(fp, str);
+ listinit5();
}
diff --git a/src/cmd/5c/peep.c b/src/cmd/5c/peep.c
index 22328c18c..143400a63 100644
--- a/src/cmd/5c/peep.c
+++ b/src/cmd/5c/peep.c
@@ -31,7 +31,7 @@
#include "gc.h"
-int xtramodes(Reg*, Adr*);
+int xtramodes(Reg*, Addr*);
void
peep(void)
@@ -281,7 +281,7 @@ uniqs(Reg *r)
}
int
-regtyp(Adr *a)
+regtyp(Addr *a)
{
if(a->type == D_REG)
@@ -309,7 +309,7 @@ int
subprop(Reg *r0)
{
Prog *p;
- Adr *v1, *v2;
+ Addr *v1, *v2;
Reg *r;
int t;
@@ -427,7 +427,7 @@ int
copyprop(Reg *r0)
{
Prog *p;
- Adr *v1, *v2;
+ Addr *v1, *v2;
Reg *r;
p = r0->prog;
@@ -441,7 +441,7 @@ copyprop(Reg *r0)
}
int
-copy1(Adr *v1, Adr *v2, Reg *r, int f)
+copy1(Addr *v1, Addr *v2, Reg *r, int f)
{
int t;
Prog *p;
@@ -525,7 +525,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f)
* The v1->v2 should be eliminated by copy propagation.
*/
void
-constprop(Adr *c1, Adr *v1, Reg *r)
+constprop(Addr *c1, Addr *v1, Reg *r)
{
Prog *p;
@@ -574,7 +574,7 @@ shiftprop(Reg *r)
Reg *r1;
Prog *p, *p1, *p2;
int n, o;
- Adr a;
+ Addr a;
p = r->prog;
if(p->to.type != D_REG)
@@ -710,7 +710,7 @@ shiftprop(Reg *r)
}
Reg*
-findpre(Reg *r, Adr *v)
+findpre(Reg *r, Addr *v)
{
Reg *r1;
@@ -730,7 +730,7 @@ findpre(Reg *r, Adr *v)
}
Reg*
-findinc(Reg *r, Reg *r2, Adr *v)
+findinc(Reg *r, Reg *r2, Addr *v)
{
Reg *r1;
Prog *p;
@@ -758,7 +758,7 @@ findinc(Reg *r, Reg *r2, Adr *v)
int
nochange(Reg *r, Reg *r2, Prog *p)
{
- Adr a[3];
+ Addr a[3];
int i, n;
if(r == r2)
@@ -788,7 +788,7 @@ nochange(Reg *r, Reg *r2, Prog *p)
}
int
-findu1(Reg *r, Adr *v)
+findu1(Reg *r, Addr *v)
{
for(; r != R; r = r->s1) {
if(r->active)
@@ -810,7 +810,7 @@ findu1(Reg *r, Adr *v)
}
int
-finduse(Reg *r, Adr *v)
+finduse(Reg *r, Addr *v)
{
Reg *r1;
@@ -820,11 +820,11 @@ finduse(Reg *r, Adr *v)
}
int
-xtramodes(Reg *r, Adr *a)
+xtramodes(Reg *r, Addr *a)
{
Reg *r1, *r2, *r3;
Prog *p, *p1;
- Adr v;
+ Addr v;
p = r->prog;
if((p->as == AMOVB || p->as == AMOVBS) && p->from.type == D_OREG) /* byte load */
@@ -911,7 +911,7 @@ xtramodes(Reg *r, Adr *a)
* 0 otherwise (not touched)
*/
int
-copyu(Prog *p, Adr *v, Adr *s)
+copyu(Prog *p, Addr *v, Addr *s)
{
switch(p->as) {
@@ -1106,7 +1106,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(v->type == D_REG) {
if(v->reg <= REGEXT && v->reg > exregoffset)
return 2;
- if(v->reg == (uchar)REGARG)
+ if(v->reg == REGARG)
return 2;
}
if(v->type == D_FREG)
@@ -1124,7 +1124,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ATEXT: /* funny */
if(v->type == D_REG)
- if(v->reg == (uchar)REGARG)
+ if(v->reg == REGARG)
return 3;
return 0;
}
@@ -1175,7 +1175,7 @@ a2type(Prog *p)
* semantics
*/
int
-copyas(Adr *a, Adr *v)
+copyas(Addr *a, Addr *v)
{
if(regtyp(v)) {
@@ -1197,7 +1197,7 @@ copyas(Adr *a, Adr *v)
* either direct or indirect
*/
int
-copyau(Adr *a, Adr *v)
+copyau(Addr *a, Addr *v)
{
if(copyas(a, v))
@@ -1217,7 +1217,7 @@ copyau(Adr *a, Adr *v)
}
int
-copyau1(Prog *p, Adr *v)
+copyau1(Prog *p, Addr *v)
{
if(regtyp(v)) {
@@ -1236,7 +1236,7 @@ copyau1(Prog *p, Adr *v)
* return failure to substitute
*/
int
-copysub(Adr *a, Adr *v, Adr *s, int f)
+copysub(Addr *a, Addr *v, Addr *s, int f)
{
if(f)
@@ -1253,7 +1253,7 @@ copysub(Adr *a, Adr *v, Adr *s, int f)
}
int
-copysub1(Prog *p1, Adr *v, Adr *s, int f)
+copysub1(Prog *p1, Addr *v, Addr *s, int f)
{
if(f)
diff --git a/src/cmd/5c/reg.c b/src/cmd/5c/reg.c
index 3d67872b4..b9ac21abd 100644
--- a/src/cmd/5c/reg.c
+++ b/src/cmd/5c/reg.c
@@ -480,8 +480,10 @@ brk:
r1 = 0; /* set */
for(r = firstr; r != R; r = r->link) {
p = r->prog;
- if(p->to.type == D_BRANCH)
+ if(p->to.type == D_BRANCH) {
p->to.offset = r->s2->pc;
+ p->to.u.branch = r->s2->prog;
+ }
r1 = r;
}
@@ -535,7 +537,7 @@ void
addmove(Reg *r, int bn, int rn, int f)
{
Prog *p, *p1;
- Adr *a;
+ Addr *a;
Var *v;
p1 = alloc(sizeof(*p1));
@@ -554,7 +556,7 @@ addmove(Reg *r, int bn, int rn, int f)
a->offset = v->offset;
a->etype = v->etype;
a->type = D_OREG;
- if(a->etype == TARRAY || a->sym == S)
+ if(a->etype == TARRAY || a->sym == nil)
a->type = D_CONST;
p1->as = AMOVW;
@@ -592,13 +594,13 @@ addmove(Reg *r, int bn, int rn, int f)
}
Bits
-mkvar(Adr *a, int docon)
+mkvar(Addr *a, int docon)
{
Var *v;
int i, t, n, et, z;
int32 o;
Bits bit;
- Sym *s;
+ LSym *s;
t = a->type;
if(t == D_REG && a->reg != NREG)
@@ -608,13 +610,13 @@ mkvar(Adr *a, int docon)
s = a->sym;
o = a->offset;
et = a->etype;
- if(s == S) {
+ if(s == nil) {
if(t != D_CONST || !docon || a->reg != NREG)
goto none;
et = TLONG;
}
if(t == D_CONST) {
- if(s == S && sval(o))
+ if(s == nil && sval(o))
goto none;
}
@@ -656,7 +658,7 @@ out:
for(z=0; z<BITS; z++)
addrs.b[z] |= bit.b[z];
if(t == D_CONST) {
- if(s == S) {
+ if(s == nil) {
for(z=0; z<BITS; z++)
consts.b[z] |= bit.b[z];
return bit;
@@ -1135,7 +1137,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
}
void
-addreg(Adr *a, int rn)
+addreg(Addr *a, int rn)
{
a->sym = 0;
diff --git a/src/cmd/5c/swt.c b/src/cmd/5c/swt.c
index 0f0c457f8..fd81a4e68 100644
--- a/src/cmd/5c/swt.c
+++ b/src/cmd/5c/swt.c
@@ -206,7 +206,7 @@ outstring(char *s, int32 n)
p->from.offset += nstring - NSNAME;
p->reg = NSNAME;
p->to.type = D_SCONST;
- memmove(p->to.sval, string, NSNAME);
+ memmove(p->to.u.sval, string, NSNAME);
mnstring = 0;
}
n--;
@@ -321,7 +321,7 @@ sextern(Sym *s, Node *a, int32 o, int32 w)
p->from.offset += o+e;
p->reg = lw;
p->to.type = D_SCONST;
- memmove(p->to.sval, a->cstring+e, lw);
+ memmove(p->to.u.sval, a->cstring+e, lw);
}
}
@@ -351,48 +351,10 @@ gextern(Sym *s, Node *a, int32 o, int32 w)
p->to.type = D_CONST;
}
-void zname(Biobuf*, Sym*, int);
-char* zaddr(char*, Adr*, int);
-void zwrite(Biobuf*, Prog*, int, int);
-void outhist(Biobuf*);
-
-void
-zwrite(Biobuf *b, Prog *p, int sf, int st)
-{
- char bf[100], *bp;
-
- bf[0] = p->as;
- bf[1] = p->scond;
- bf[2] = p->reg;
- bf[3] = p->lineno;
- bf[4] = p->lineno>>8;
- bf[5] = p->lineno>>16;
- bf[6] = p->lineno>>24;
- bp = zaddr(bf+7, &p->from, sf);
- bp = zaddr(bp, &p->to, st);
- Bwrite(b, bf, bp-bf);
-}
-
void
outcode(void)
{
- struct { Sym *sym; short type; } h[NSYM];
- Prog *p;
- Sym *s;
- int sf, st, t, sym;
-
- if(debug['S']) {
- for(p = firstp; p != P; p = p->link)
- if(p->as != ADATA && p->as != AGLOBL)
- pc--;
- for(p = firstp; p != P; p = p->link) {
- print("%P\n", p);
- if(p->as != ADATA && p->as != AGLOBL)
- pc++;
- }
- }
-
- Bprint(&outbuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
+ Bprint(&outbuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&outbuf, "\n");
Bprint(&outbuf, "$$ // exports\n\n");
@@ -403,249 +365,10 @@ outcode(void)
}
Bprint(&outbuf, "!\n");
- outhist(&outbuf);
- for(sym=0; sym<NSYM; sym++) {
- h[sym].sym = S;
- h[sym].type = 0;
- }
- sym = 1;
- for(p = firstp; p != P; p = p->link) {
- jackpot:
- sf = 0;
- s = p->from.sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = p->from.name;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- s->sym = sym;
- zname(&outbuf, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = p->to.sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = p->to.name;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- s->sym = sym;
- zname(&outbuf, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- zwrite(&outbuf, p, sf, st);
- }
- firstp = P;
+ writeobj(ctxt, &outbuf);
lastp = P;
}
-void
-outhist(Biobuf *b)
-{
- Hist *h;
- char *p, *q, *op, c;
- Prog pg;
- int n;
- char *tofree;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
- pg = zprog;
- pg.as = AHISTORY;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p != nil && goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- op = 0;
- if(systemtype(Windows) && p && p[1] == ':'){
- c = p[2];
- } else if(p && p[0] != c && h->offset == 0 && pathname){
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname;
- c = p[2];
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = utfrune(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- BPUTC(b, ANAME);
- BPUTC(b, D_FILE);
- BPUTC(b, 1);
- BPUTC(b, '<');
- Bwrite(b, p, n);
- BPUTC(b, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- pg.lineno = h->line;
- pg.to.type = zprog.to.type;
- pg.to.offset = h->offset;
- if(h->offset)
- pg.to.type = D_CONST;
-
- zwrite(b, &pg, 0, 0);
-
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- char *n, bf[7];
- uint32 sig;
-
- n = s->name;
- if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
- sig = sign(s);
- bf[0] = ASIGNAME;
- bf[1] = sig;
- bf[2] = sig>>8;
- bf[3] = sig>>16;
- bf[4] = sig>>24;
- bf[5] = t;
- bf[6] = s->sym;
- Bwrite(b, bf, 7);
- s->sig = SIGDONE;
- }
- else{
- bf[0] = ANAME;
- bf[1] = t; /* type */
- bf[2] = s->sym; /* sym */
- Bwrite(b, bf, 3);
- }
- Bwrite(b, n, strlen(n)+1);
-}
-
-char*
-zaddr(char *bp, Adr *a, int s)
-{
- int32 l;
- Ieee e;
-
- bp[0] = a->type;
- bp[1] = a->reg;
- bp[2] = s;
- bp[3] = a->name;
- bp[4] = 0;
- bp += 5;
- switch(a->type) {
- default:
- diag(Z, "unknown type %d in zaddr", a->type);
-
- case D_NONE:
- case D_REG:
- case D_FREG:
- case D_PSR:
- break;
-
- case D_CONST2:
- l = a->offset2;
- bp[0] = l;
- bp[1] = l>>8;
- bp[2] = l>>16;
- bp[3] = l>>24;
- bp += 4; // fall through
- case D_OREG:
- case D_CONST:
- case D_BRANCH:
- case D_SHIFT:
- l = a->offset;
- bp[0] = l;
- bp[1] = l>>8;
- bp[2] = l>>16;
- bp[3] = l>>24;
- bp += 4;
- break;
-
- case D_SCONST:
- memmove(bp, a->sval, NSNAME);
- bp += NSNAME;
- break;
-
- case D_FCONST:
- ieeedtod(&e, a->dval);
- l = e.l;
- bp[0] = l;
- bp[1] = l>>8;
- bp[2] = l>>16;
- bp[3] = l>>24;
- bp += 4;
- l = e.h;
- bp[0] = l;
- bp[1] = l>>8;
- bp[2] = l>>16;
- bp[3] = l>>24;
- bp += 4;
- break;
- }
- return bp;
-}
-
int32
align(int32 i, Type *t, int op, int32 *maxalign)
{
diff --git a/src/cmd/5c/txt.c b/src/cmd/5c/txt.c
index 6d9b69d00..a753510ca 100644
--- a/src/cmd/5c/txt.c
+++ b/src/cmd/5c/txt.c
@@ -31,13 +31,22 @@
#include "gc.h"
+
+int thechar = '5';
+char *thestring = "arm";
+
+LinkArch *thelinkarch = &linkarm;
+
+void
+linkarchinit(void)
+{
+}
+
void
ginit(void)
{
Type *t;
- thechar = '5';
- thestring = "arm";
exregoffset = REGEXT;
exfregoffset = FREGEXT;
listinit();
@@ -48,7 +57,6 @@ ginit(void)
breakpc = -1;
continpc = -1;
cases = C;
- firstp = P;
lastp = P;
tfield = types[TLONG];
@@ -149,17 +157,17 @@ gclean(void)
void
nextpc(void)
{
+ Plist *pl;
p = alloc(sizeof(*p));
*p = zprog;
p->lineno = nearln;
pc++;
- if(firstp == P) {
- firstp = p;
- lastp = p;
- return;
- }
- lastp->link = p;
+ if(lastp == nil) {
+ pl = linknewplist(ctxt);
+ pl->firstpc = p;
+ } else
+ lastp->link = p;
lastp = p;
}
@@ -422,7 +430,7 @@ regind(Node *n, Node *nn)
void
raddr(Node *n, Prog *p)
{
- Adr a;
+ Addr a;
naddr(n, &a);
if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
@@ -440,7 +448,7 @@ raddr(Node *n, Prog *p)
}
void
-naddr(Node *n, Adr *a)
+naddr(Node *n, Addr *a)
{
int32 v;
@@ -455,7 +463,7 @@ naddr(Node *n, Adr *a)
case OREGISTER:
a->type = D_REG;
- a->sym = S;
+ a->sym = nil;
a->reg = n->reg;
if(a->reg >= NREG) {
a->type = D_FREG;
@@ -477,7 +485,7 @@ naddr(Node *n, Adr *a)
case OINDREG:
a->type = D_OREG;
- a->sym = S;
+ a->sym = nil;
a->offset = n->xoffset;
a->reg = n->reg;
break;
@@ -486,7 +494,7 @@ naddr(Node *n, Adr *a)
a->etype = n->etype;
a->type = D_OREG;
a->name = D_STATIC;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
a->offset = n->xoffset;
if(n->class == CSTATIC)
break;
@@ -505,11 +513,11 @@ naddr(Node *n, Adr *a)
goto bad;
case OCONST:
- a->sym = S;
+ a->sym = nil;
a->reg = NREG;
if(typefd[n->type->etype]) {
a->type = D_FCONST;
- a->dval = n->fconst;
+ a->u.dval = n->fconst;
} else {
a->type = D_CONST;
a->offset = n->vconst;
@@ -930,7 +938,7 @@ void
gopcode(int o, Node *f1, Node *f2, Node *t)
{
int a, et;
- Adr ta;
+ Addr ta;
et = TLONG;
if(f1 != Z && f1->type != T)
@@ -1177,7 +1185,7 @@ gpseudo(int a, Sym *s, Node *n)
nextpc();
p->as = a;
p->from.type = D_OREG;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.name = D_EXTERN;
switch(a) {
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c
index 2d260e72d..9011b2022 100644
--- a/src/cmd/5g/cgen.c
+++ b/src/cmd/5g/cgen.c
@@ -254,6 +254,7 @@ cgen(Node *n, Node *res)
case OOR:
case OXOR:
case OADD:
+ case OADDPTR:
case OMUL:
a = optoas(n->op, nl->type);
goto sbop;
@@ -604,6 +605,7 @@ agen(Node *n, Node *res)
// The generated code is just going to panic, so it need not
// be terribly efficient. See issue 3670.
tempname(&n1, n->type);
+ gvardef(&n1);
clearfat(&n1);
regalloc(&n2, types[tptr], res);
gins(AMOVW, &n1, &n2);
@@ -1410,10 +1412,11 @@ stkof(Node *n)
void
sgen(Node *n, Node *res, int64 w)
{
- Node dst, src, tmp, nend;
+ Node dst, src, tmp, nend, r0, r1, r2, *f;
int32 c, odst, osrc;
int dir, align, op;
Prog *p, *ploop;
+ NodeList *l;
if(debug['g']) {
print("\nsgen w=%lld\n", w);
@@ -1439,6 +1442,13 @@ sgen(Node *n, Node *res, int64 w)
return;
}
+ // If copying .args, that's all the results, so record definition sites
+ // for them for the liveness analysis.
+ if(res->op == ONAME && strcmp(res->sym->name, ".args") == 0)
+ for(l = curfn->dcl; l != nil; l = l->next)
+ if(l->n->class == PPARAMOUT)
+ gvardef(l->n);
+
// Avoid taking the address for simple enough types.
if(componentgen(n, res))
return;
@@ -1480,18 +1490,59 @@ sgen(Node *n, Node *res, int64 w)
}
if(osrc%align != 0 || odst%align != 0)
fatal("sgen: unaligned offset src %d or dst %d (align %d)", osrc, odst, align);
+
// if we are copying forward on the stack and
// the src and dst overlap, then reverse direction
dir = align;
if(osrc < odst && odst < osrc+w)
dir = -dir;
+ if(op == AMOVW && dir > 0 && c >= 4 && c <= 128) {
+ r0.op = OREGISTER;
+ r0.val.u.reg = REGALLOC_R0;
+ r1.op = OREGISTER;
+ r1.val.u.reg = REGALLOC_R0 + 1;
+ r2.op = OREGISTER;
+ r2.val.u.reg = REGALLOC_R0 + 2;
+
+ regalloc(&src, types[tptr], &r1);
+ regalloc(&dst, types[tptr], &r2);
+ if(n->ullman >= res->ullman) {
+ // eval n first
+ agen(n, &src);
+ if(res->op == ONAME)
+ gvardef(res);
+ agen(res, &dst);
+ } else {
+ // eval res first
+ if(res->op == ONAME)
+ gvardef(res);
+ agen(res, &dst);
+ agen(n, &src);
+ }
+ regalloc(&tmp, types[tptr], &r0);
+ f = sysfunc("duffcopy");
+ p = gins(ADUFFCOPY, N, f);
+ afunclit(&p->to, f);
+ // 8 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s
+ p->to.offset = 8*(128-c);
+
+ regfree(&tmp);
+ regfree(&src);
+ regfree(&dst);
+ return;
+ }
+
if(n->ullman >= res->ullman) {
agenr(n, &dst, res); // temporarily use dst
regalloc(&src, types[tptr], N);
gins(AMOVW, &dst, &src);
+ if(res->op == ONAME)
+ gvardef(res);
agen(res, &dst);
} else {
+ if(res->op == ONAME)
+ gvardef(res);
agenr(res, &dst, res);
agenr(n, &src, N);
}
@@ -1624,8 +1675,17 @@ componentgen(Node *nr, Node *nl)
freer = 1;
}
+ // nl and nr are 'cadable' which basically means they are names (variables) now.
+ // If they are the same variable, don't generate any code, because the
+ // VARDEF we generate will mark the old value as dead incorrectly.
+ // (And also the assignments are useless.)
+ if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
+ goto yes;
+
switch(nl->type->etype) {
case TARRAY:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(nl->type->type);
@@ -1656,6 +1716,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TSTRING:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
@@ -1677,6 +1739,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TINTER:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
diff --git a/src/cmd/5g/galign.c b/src/cmd/5g/galign.c
index 1fbf633f9..a62102ef8 100644
--- a/src/cmd/5g/galign.c
+++ b/src/cmd/5g/galign.c
@@ -8,6 +8,12 @@
int thechar = '5';
char* thestring = "arm";
+LinkArch* thelinkarch = &linkarm;
+
+void
+linkarchinit(void)
+{
+}
vlong MAXWIDTH = (1LL<<32) - 1;
@@ -28,6 +34,7 @@ betypeinit(void)
{
widthptr = 4;
widthint = 4;
+ widthreg = 4;
zprog.link = P;
zprog.as = AGOK;
@@ -38,5 +45,5 @@ betypeinit(void)
zprog.from.reg = NREG;
zprog.to = zprog.from;
- listinit();
+ listinit5();
}
diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h
index 860817f69..413e93c24 100644
--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -9,44 +9,6 @@
#include "../gc/go.h"
#include "../5l/5.out.h"
-typedef struct Addr Addr;
-
-struct Addr
-{
- int32 offset;
- int32 offset2;
-
- union {
- double dval;
- vlong vval;
- Prog* branch;
- char sval[NSNAME];
- } u;
-
- Sym* sym;
- Sym* gotype;
- Node* node;
- int width;
- uchar type;
- char name;
- uchar reg;
- uchar etype;
-};
-#define A ((Addr*)0)
-
-struct Prog
-{
- uint32 loc; // pc offset in this func
- uint32 lineno; // source line that generated this
- Prog* link; // next instruction in this func
- void* opt; // for optimizer passes
- short as; // opcode
- uchar reg; // doubles as width in DATA op
- uchar scond;
- Addr from; // src address
- Addr to; // dst address
-};
-
#define TEXTFLAG reg
#define REGALLOC_R0 0
@@ -58,7 +20,6 @@ EXTERN int32 dynloc;
EXTERN uchar reg[REGALLOC_FMAX+1];
EXTERN int32 pcloc; // instruction counter
EXTERN Strlit emptystring;
-extern char* anames[];
EXTERN Prog zprog;
EXTERN Node* newproc;
EXTERN Node* deferproc;
@@ -67,7 +28,6 @@ EXTERN Node* panicindex;
EXTERN Node* panicslice;
EXTERN Node* throwreturn;
extern long unmappedzero;
-EXTERN int maxstksize;
/*
* gen.c
@@ -156,16 +116,6 @@ void datastring(char*, int, Addr*);
/*
* list.c
*/
-int Aconv(Fmt*);
-int Cconv(Fmt*);
-int Dconv(Fmt*);
-int Mconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Yconv(Fmt*);
void listinit(void);
void zaddr(Biobuf*, Addr*, int, int);
-
-#pragma varargck type "D" Addr*
-#pragma varargck type "M" Addr*
diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c
index 040c3d2a9..fb32c2f36 100644
--- a/src/cmd/5g/ggen.c
+++ b/src/cmd/5g/ggen.c
@@ -9,78 +9,114 @@
#include "gg.h"
#include "opt.h"
-static Prog* appendp(Prog*, int, int, int, int32, int, int, int32);
+static Prog* appendpp(Prog*, int, int, int, int32, int, int, int32);
+static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0);
void
-defframe(Prog *ptxt, Bvec *bv)
+defframe(Prog *ptxt)
{
- int i, j, first;
- uint32 frame;
- Prog *p, *p1;
-
+ uint32 frame, r0;
+ Prog *p;
+ vlong hi, lo;
+ NodeList *l;
+ Node *n;
+
// fill in argument size
ptxt->to.type = D_CONST2;
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
- if(stksize > maxstksize)
- maxstksize = stksize;
- frame = rnd(maxstksize+maxarg, widthptr);
+ frame = rnd(stksize+maxarg, widthptr);
ptxt->to.offset = frame;
- maxstksize = 0;
-
- // insert code to clear pointered part of the frame,
+
+ // insert code to contain ambiguously live variables
// so that garbage collector only sees initialized values
// when it looks for pointers.
p = ptxt;
- while(p->link->as == AFUNCDATA || p->link->as == APCDATA || p->link->as == ATYPE)
- p = p->link;
- if(stkzerosize >= 8*widthptr) {
- p = appendp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
- p = appendp(p, AADD, D_CONST, NREG, 4+frame-stkzerosize, D_REG, 1, 0);
+ lo = hi = 0;
+ r0 = 0;
+ for(l=curfn->dcl; l != nil; l = l->next) {
+ n = l->n;
+ if(!n->needzero)
+ continue;
+ if(n->class != PAUTO)
+ fatal("needzero class %d", n->class);
+ if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
+ fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
+ if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthptr) {
+ // merge with range we already have
+ lo = rnd(n->xoffset, widthptr);
+ continue;
+ }
+ // zero old range
+ p = zerorange(p, frame, lo, hi, &r0);
+
+ // set new range
+ hi = n->xoffset + n->type->width;
+ lo = n->xoffset;
+ }
+ // zero final range
+ zerorange(p, frame, lo, hi, &r0);
+}
+
+static Prog*
+zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
+{
+ vlong cnt, i;
+ Prog *p1;
+ Node *f;
+
+ cnt = hi - lo;
+ if(cnt == 0)
+ return p;
+ if(*r0 == 0) {
+ p = appendpp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
+ *r0 = 1;
+ }
+ if(cnt < 4*widthptr) {
+ for(i = 0; i < cnt; i += widthptr)
+ p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame+lo+i);
+ } else if(cnt <= 128*widthptr) {
+ p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
p->reg = REGSP;
- p = appendp(p, AADD, D_CONST, NREG, stkzerosize, D_REG, 2, 0);
+ p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
+ f = sysfunc("duffzero");
+ naddr(f, &p->to, 1);
+ afunclit(&p->to, f);
+ p->to.offset = 4*(128-cnt/widthptr);
+ } else {
+ p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
+ p->reg = REGSP;
+ p = appendpp(p, AADD, D_CONST, NREG, cnt, D_REG, 2, 0);
p->reg = 1;
- p1 = p = appendp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4);
+ p1 = p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4);
p->scond |= C_PBIT;
- p = appendp(p, ACMP, D_REG, 1, 0, D_NONE, 0, 0);
+ p = appendpp(p, ACMP, D_REG, 1, 0, D_NONE, 0, 0);
p->reg = 2;
- p = appendp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
+ p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
patch(p, p1);
- } else {
- first = 1;
- j = (stkptrsize - stkzerosize)/widthptr * 2;
- for(i=0; i<stkzerosize; i+=widthptr) {
- if(bvget(bv, j) || bvget(bv, j+1)) {
- if(first) {
- p = appendp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
- first = 0;
- }
- p = appendp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame-stkzerosize+i);
- }
- j += 2;
- }
}
+ return p;
}
-static Prog*
-appendp(Prog *p, int as, int ftype, int freg, int32 foffset, int ttype, int treg, int32 toffset)
-{
- Prog *q;
-
- q = mal(sizeof(*q));
- clearp(q);
- q->as = as;
- q->lineno = p->lineno;
- q->from.type = ftype;
- q->from.reg = freg;
- q->from.offset = foffset;
- q->to.type = ttype;
- q->to.reg = treg;
- q->to.offset = toffset;
- q->link = p->link;
- p->link = q;
- return q;
+static Prog*
+appendpp(Prog *p, int as, int ftype, int freg, int32 foffset, int ttype, int treg, int32 toffset)
+{
+ Prog *q;
+
+ q = mal(sizeof(*q));
+ clearp(q);
+ q->as = as;
+ q->lineno = p->lineno;
+ q->from.type = ftype;
+ q->from.reg = freg;
+ q->from.offset = foffset;
+ q->to.type = ttype;
+ q->to.reg = treg;
+ q->to.offset = toffset;
+ q->link = p->link;
+ p->link = q;
+ return q;
}
// Sweep the prog list to mark any used nodes.
@@ -88,13 +124,13 @@ void
markautoused(Prog* p)
{
for (; p; p = p->link) {
- if (p->as == ATYPE)
+ if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
continue;
- if (p->from.name == D_AUTO && p->from.node)
+ if (p->from.node)
p->from.node->used = 1;
- if (p->to.name == D_AUTO && p->to.node)
+ if (p->to.node)
p->to.node->used = 1;
}
}
@@ -110,6 +146,16 @@ fixautoused(Prog* p)
*lp = p->link;
continue;
}
+ if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) {
+ // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
+ // VARDEFs are interspersed with other code, and a jump might be using the
+ // VARDEF as a target. Replace with a no-op instead. A later pass will remove
+ // the no-ops.
+ p->to.type = D_NONE;
+ p->to.node = N;
+ p->as = ANOP;
+ continue;
+ }
if (p->from.name == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta;
@@ -245,7 +291,9 @@ ginscall(Node *f, int proc)
nodconst(&con, types[TINT32], 0);
p = gins(ACMP, &con, N);
p->reg = 0;
- patch(gbranch(ABNE, T, -1), retpc);
+ p = gbranch(ABEQ, T, +1);
+ cgen_ret(N);
+ patch(p, pc);
}
break;
}
@@ -459,16 +507,16 @@ cgen_ret(Node *n)
{
Prog *p;
- genlist(n->list); // copy out args
- if(hasdefer || curfn->exit) {
- gjmp(retpc);
- return;
- }
+ if(n != N)
+ genlist(n->list); // copy out args
+ if(hasdefer)
+ ginscall(deferreturn, 0);
+ genlist(curfn->exit);
p = gins(ARET, N, N);
- if(n->op == ORETJMP) {
+ if(n != N && n->op == ORETJMP) {
p->to.name = D_EXTERN;
p->to.type = D_CONST;
- p->to.sym = n->left->sym;
+ p->to.sym = linksym(n->left->sym);
}
}
@@ -816,14 +864,13 @@ void
clearfat(Node *nl)
{
uint32 w, c, q;
- Node dst, nc, nz, end;
+ Node dst, nc, nz, end, r0, r1, *f;
Prog *p, *pl;
/* clear a fat object */
if(debug['g'])
dump("\nclearfat", nl);
-
w = nl->type->width;
// Avoid taking the address for simple enough types.
if(componentgen(N, nl))
@@ -832,13 +879,17 @@ clearfat(Node *nl)
c = w % 4; // bytes
q = w / 4; // quads
- regalloc(&dst, types[tptr], N);
+ r0.op = OREGISTER;
+ r0.val.u.reg = REGALLOC_R0;
+ r1.op = OREGISTER;
+ r1.val.u.reg = REGALLOC_R0 + 1;
+ regalloc(&dst, types[tptr], &r1);
agen(nl, &dst);
nodconst(&nc, types[TUINT32], 0);
- regalloc(&nz, types[TUINT32], 0);
+ regalloc(&nz, types[TUINT32], &r0);
cgen(&nc, &nz);
- if(q >= 4) {
+ if(q > 128) {
regalloc(&end, types[tptr], N);
p = gins(AMOVW, &dst, &end);
p->from.type = D_CONST;
@@ -855,6 +906,12 @@ clearfat(Node *nl)
patch(gbranch(ABNE, T, 0), pl);
regfree(&end);
+ } else if(q >= 4) {
+ f = sysfunc("duffzero");
+ p = gins(ADUFFZERO, N, f);
+ afunclit(&p->to, f);
+ // 4 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s
+ p->to.offset = 4*(128-q);
} else
while(q > 0) {
p = gins(AMOVW, &nz, &dst);
@@ -901,7 +958,7 @@ expandchecks(Prog *firstp)
p1->link = p->link;
p->link = p1;
p1->lineno = p->lineno;
- p1->loc = 9999;
+ p1->pc = 9999;
p1->as = AMOVW;
p1->from.type = D_REG;
p1->from.reg = reg;
diff --git a/src/cmd/5g/gobj.c b/src/cmd/5g/gobj.c
index 212ffc271..5e988878f 100644
--- a/src/cmd/5g/gobj.c
+++ b/src/cmd/5g/gobj.c
@@ -32,235 +32,6 @@
#include <libc.h>
#include "gg.h"
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- BPUTC(b, ANAME); /* as */
- BPUTC(b, t); /* type */
- BPUTC(b, s->sym); /* sym */
-
- Bputname(b, s);
-}
-
-void
-zfile(Biobuf *b, char *p, int n)
-{
- BPUTC(b, ANAME);
- BPUTC(b, D_FILE);
- BPUTC(b, 1);
- BPUTC(b, '<');
- Bwrite(b, p, n);
- BPUTC(b, 0);
-}
-
-void
-zhist(Biobuf *b, int line, vlong offset)
-{
- Addr a;
-
- BPUTC(b, AHISTORY);
- BPUTC(b, C_SCOND_NONE);
- BPUTC(b, NREG);
- BPUTLE4(b, line);
- zaddr(b, &zprog.from, 0, 0);
- a = zprog.to;
- if(offset != 0) {
- a.offset = offset;
- a.type = D_CONST;
- }
- zaddr(b, &a, 0, 0);
-}
-
-void
-zaddr(Biobuf *b, Addr *a, int s, int gotype)
-{
- int32 l;
- uint64 e;
- int i;
- char *n;
-
- switch(a->type) {
- case D_STATIC:
- case D_AUTO:
- case D_EXTERN:
- case D_PARAM:
- // TODO(kaib): remove once everything seems to work
- fatal("We should no longer generate these as types");
-
- default:
- BPUTC(b, a->type);
- BPUTC(b, a->reg);
- BPUTC(b, s);
- BPUTC(b, a->name);
- BPUTC(b, gotype);
- }
-
- switch(a->type) {
- default:
- print("unknown type %d in zaddr\n", a->type);
-
- case D_NONE:
- case D_REG:
- case D_FREG:
- case D_PSR:
- break;
-
- case D_CONST2:
- l = a->offset2;
- BPUTLE4(b, l); // fall through
- case D_OREG:
- case D_CONST:
- case D_SHIFT:
- case D_STATIC:
- case D_AUTO:
- case D_EXTERN:
- case D_PARAM:
- l = a->offset;
- BPUTLE4(b, l);
- break;
-
- case D_BRANCH:
- if(a->u.branch == nil)
- fatal("unpatched branch");
- a->offset = a->u.branch->loc;
- l = a->offset;
- BPUTLE4(b, l);
- break;
-
- case D_SCONST:
- n = a->u.sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(b, *n);
- n++;
- }
- break;
-
- case D_REGREG:
- case D_REGREG2:
- BPUTC(b, a->offset);
- break;
-
- case D_FCONST:
- ieeedtod(&e, a->u.dval);
- BPUTLE4(b, e);
- BPUTLE4(b, e >> 32);
- break;
- }
-}
-
-static struct {
- struct { Sym *sym; short type; } h[NSYM];
- int sym;
-} z;
-
-static void
-zsymreset(void)
-{
- for(z.sym=0; z.sym<NSYM; z.sym++) {
- z.h[z.sym].sym = S;
- z.h[z.sym].type = 0;
- }
- z.sym = 1;
-}
-
-static int
-zsym(Sym *s, int t, int *new)
-{
- int i;
-
- *new = 0;
- if(s == S)
- return 0;
-
- i = s->sym;
- if(i < 0 || i >= NSYM)
- i = 0;
- if(z.h[i].type == t && z.h[i].sym == s)
- return i;
- i = z.sym;
- s->sym = i;
- zname(bout, s, t);
- z.h[i].sym = s;
- z.h[i].type = t;
- if(++z.sym >= NSYM)
- z.sym = 1;
- *new = 1;
- return i;
-}
-
-static int
-zsymaddr(Addr *a, int *new)
-{
- int t;
-
- t = a->name;
- if(t == D_ADDR)
- t = a->name;
- return zsym(a->sym, t, new);
-}
-
-void
-dumpfuncs(void)
-{
- Plist *pl;
- int sf, st, gf, gt, new;
- Sym *s;
- Prog *p;
-
- zsymreset();
-
- // fix up pc
- pcloc = 0;
- for(pl=plist; pl!=nil; pl=pl->link) {
- if(isblank(pl->name))
- continue;
- for(p=pl->firstpc; p!=P; p=p->link) {
- p->loc = pcloc;
- if(p->as != ADATA && p->as != AGLOBL)
- pcloc++;
- }
- }
-
- // put out functions
- for(pl=plist; pl!=nil; pl=pl->link) {
- if(isblank(pl->name))
- continue;
-
- // -S prints code; -SS prints code and data
- if(debug['S'] && (pl->name || debug['S']>1)) {
- s = S;
- if(pl->name != N)
- s = pl->name->sym;
- print("\n--- prog list \"%S\" ---\n", s);
- for(p=pl->firstpc; p!=P; p=p->link)
- print("%P\n", p);
- }
-
- for(p=pl->firstpc; p!=P; p=p->link) {
- for(;;) {
- sf = zsymaddr(&p->from, &new);
- gf = zsym(p->from.gotype, D_EXTERN, &new);
- if(new && sf == gf)
- continue;
- st = zsymaddr(&p->to, &new);
- if(new && (st == sf || st == gf))
- continue;
- gt = zsym(p->to.gotype, D_EXTERN, &new);
- if(new && (gt == sf || gt == gf || gt == st))
- continue;
- break;
- }
-
- BPUTC(bout, p->as);
- BPUTC(bout, p->scond);
- BPUTC(bout, p->reg);
- BPUTLE4(bout, p->lineno);
- zaddr(bout, &p->from, sf, gf);
- zaddr(bout, &p->to, st, gt);
- }
- }
-}
-
int
dsname(Sym *sym, int off, char *t, int n)
{
@@ -272,7 +43,7 @@ dsname(Sym *sym, int off, char *t, int n)
p->from.etype = TINT32;
p->from.offset = off;
p->from.reg = NREG;
- p->from.sym = sym;
+ p->from.sym = linksym(sym);
p->reg = n;
@@ -299,7 +70,7 @@ datastring(char *s, int len, Addr *a)
a->etype = TINT32;
a->offset = widthptr+4; // skip header
a->reg = NREG;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
}
@@ -318,7 +89,7 @@ datagostring(Strlit *sval, Addr *a)
a->etype = TINT32;
a->offset = 0; // header
a->reg = NREG;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
}
@@ -401,7 +172,7 @@ dstringptr(Sym *s, int off, char *str)
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->reg = widthptr;
@@ -425,7 +196,7 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->reg = widthptr;
datagostring(lit, &p->to);
@@ -453,27 +224,6 @@ dgostringptr(Sym *s, int off, char *str)
}
int
-duintxx(Sym *s, int off, uint64 v, int wid)
-{
- Prog *p;
-
- off = rnd(off, wid);
-
- p = gins(ADATA, N, N);
- p->from.type = D_OREG;
- p->from.name = D_EXTERN;
- p->from.sym = s;
- p->from.offset = off;
- p->reg = wid;
- p->to.type = D_CONST;
- p->to.name = D_NONE;
- p->to.offset = v;
- off += wid;
-
- return off;
-}
-
-int
dsymptr(Sym *s, int off, Sym *x, int xoff)
{
Prog *p;
@@ -483,12 +233,12 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
p = gins(ADATA, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->reg = widthptr;
p->to.type = D_CONST;
p->to.name = D_EXTERN;
- p->to.sym = x;
+ p->to.sym = linksym(x);
p->to.offset = xoff;
off += widthptr;
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c
index 27749b7a7..f66c87b5a 100644
--- a/src/cmd/5g/gsubr.c
+++ b/src/cmd/5g/gsubr.c
@@ -50,7 +50,7 @@ clearp(Prog *p)
p->to.type = D_NONE;
p->to.name = D_NONE;
p->to.reg = NREG;
- p->loc = pcloc;
+ p->pc = pcloc;
pcloc++;
}
@@ -138,7 +138,7 @@ patch(Prog *p, Prog *to)
if(p->to.type != D_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
- p->to.offset = to->loc;
+ p->to.offset = to->pc;
}
Prog*
@@ -162,12 +162,7 @@ newplist(void)
{
Plist *pl;
- pl = mal(sizeof(*pl));
- if(plist == nil)
- plist = pl;
- else
- plast->link = pl;
- plast = pl;
+ pl = linknewplist(ctxt);
pc = mal(sizeof(*pc));
clearp(pc);
@@ -200,8 +195,8 @@ ggloblnod(Node *nam)
p = gins(AGLOBL, nam, N);
p->lineno = nam->lineno;
- p->from.gotype = ngotype(nam);
- p->to.sym = S;
+ p->from.sym->gotype = linksym(ngotype(nam));
+ p->to.sym = nil;
p->to.type = D_CONST;
p->to.offset = nam->type->width;
if(nam->readonly)
@@ -228,7 +223,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
p = gins(AGLOBL, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->to.type = D_CONST;
p->to.name = D_NONE;
p->to.offset = width;
@@ -246,7 +241,7 @@ gtrack(Sym *s)
p = gins(AUSEFIELD, N, N);
p->from.type = D_OREG;
p->from.name = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
}
int
@@ -275,7 +270,7 @@ afunclit(Addr *a, Node *n)
if(a->type == D_CONST && a->name == D_EXTERN || a->type == D_REG) {
a->type = D_OREG;
if(n->op == ONAME)
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
}
}
@@ -475,6 +470,7 @@ Node*
nodarg(Type *t, int fp)
{
Node *n;
+ NodeList *l;
Type *first;
Iter savet;
@@ -496,6 +492,14 @@ nodarg(Type *t, int fp)
if(t->etype != TFIELD)
fatal("nodarg: not field %T", t);
+ if(fp == 1) {
+ for(l=curfn->dcl; l; l=l->next) {
+ n = l->n;
+ if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
+ return n;
+ }
+ }
+
n = nod(ONAME, N, N);
n->type = t->type;
n->sym = t->sym;
@@ -1196,10 +1200,12 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
void
naddr(Node *n, Addr *a, int canemitcode)
{
+ Sym *s;
+
a->type = D_NONE;
a->name = D_NONE;
a->reg = NREG;
- a->gotype = S;
+ a->gotype = nil;
a->node = N;
a->etype = 0;
if(n == N)
@@ -1223,7 +1229,7 @@ naddr(Node *n, Addr *a, int canemitcode)
a->type = D_FREG;
a->reg = n->val.u.reg - REGALLOC_F0;
}
- a->sym = S;
+ a->sym = nil;
break;
case OINDEX:
@@ -1250,7 +1256,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OINDREG:
a->type = D_OREG;
a->reg = n->val.u.reg;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
a->offset = n->xoffset;
break;
@@ -1260,22 +1266,24 @@ naddr(Node *n, Addr *a, int canemitcode)
a->etype = simtype[n->left->type->etype];
a->width = n->left->type->width;
a->offset = n->xoffset;
- a->sym = n->left->sym;
+ a->sym = linksym(n->left->sym);
a->type = D_OREG;
a->name = D_PARAM;
a->node = n->left->orig;
break;
case OCLOSUREVAR:
+ if(!curfn->needctxt)
+ fatal("closurevar without needctxt");
a->type = D_OREG;
a->reg = 7;
a->offset = n->xoffset;
- a->sym = S;
+ a->sym = nil;
break;
case OCFUNC:
naddr(n->left, a, canemitcode);
- a->sym = n->left->sym;
+ a->sym = linksym(n->left->sym);
break;
case ONAME:
@@ -1287,17 +1295,17 @@ naddr(Node *n, Addr *a, int canemitcode)
a->width = n->type->width;
}
a->offset = n->xoffset;
- a->sym = n->sym;
+ s = n->sym;
a->node = n->orig;
//if(a->node >= (Node*)&n)
// fatal("stack node");
- if(a->sym == S)
- a->sym = lookup(".noname");
+ if(s == S)
+ s = lookup(".noname");
if(n->method) {
if(n->type != T)
if(n->type->sym != S)
if(n->type->sym->pkg != nil)
- a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
+ s = pkglookup(s->name, n->type->sym->pkg);
}
a->type = D_OREG;
@@ -1317,9 +1325,10 @@ naddr(Node *n, Addr *a, int canemitcode)
case PFUNC:
a->name = D_EXTERN;
a->type = D_CONST;
- a->sym = funcsym(a->sym);
+ s = funcsym(s);
break;
}
+ a->sym = linksym(s);
break;
case OLITERAL:
@@ -1333,7 +1342,7 @@ naddr(Node *n, Addr *a, int canemitcode)
break;
case CTINT:
case CTRUNE:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
@@ -1341,12 +1350,12 @@ naddr(Node *n, Addr *a, int canemitcode)
datagostring(n->val.u.sval, a);
break;
case CTBOOL:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = n->val.u.bval;
break;
case CTNIL:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = 0;
break;
@@ -1366,7 +1375,7 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // ptr(nil)
- a->etype = simtype[TUINTPTR];
+ a->etype = simtype[tptr];
a->offset += Array_array;
a->width = widthptr;
break;
@@ -1592,6 +1601,7 @@ optoas(int op, Type *t)
case CASE(OADD, TINT32):
case CASE(OADD, TUINT32):
case CASE(OADD, TPTR32):
+ case CASE(OADDPTR, TPTR32):
a = AADD;
break;
diff --git a/src/cmd/5g/list.c b/src/cmd/5g/list.c
deleted file mode 100644
index 6c3f1d744..000000000
--- a/src/cmd/5g/list.c
+++ /dev/null
@@ -1,342 +0,0 @@
-// Derived from 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 "gg.h"
-
-// TODO(kaib): make 5g/list.c congruent with 5l/list.c
-
-static int sconsize;
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv); // as
- fmtinstall('C', Cconv); // conditional execution bit
- fmtinstall('P', Pconv); // Prog*
- fmtinstall('D', Dconv); // Addr*
- fmtinstall('Y', Yconv); // sconst
- fmtinstall('R', Rconv); // register
- fmtinstall('M', Mconv); // names
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ], str1[STRINGSZ];
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- sconsize = 8;
- switch(p->as) {
- default:
- snprint(str1, sizeof(str1), "%A%C", p->as, p->scond);
- if(p->reg == NREG && p->as != AGLOBL)
- snprint(str, sizeof(str), "%.4d (%L) %-7s %D,%D",
- p->loc, p->lineno, str1, &p->from, &p->to);
- else
- if (p->from.type != D_FREG) {
- snprint(str, sizeof(str), "%.4d (%L) %-7s %D,R%d,%D",
- p->loc, p->lineno, str1, &p->from, p->reg, &p->to);
- } else
- snprint(str, sizeof(str), "%.4d (%L) %-7A%C %D,F%d,%D",
- p->loc, p->lineno, p->as, p->scond, &p->from, p->reg, &p->to);
- break;
-
- case ADATA:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
- p->loc, p->lineno, p->as, &p->from, p->reg, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ];
- const char *op;
- Addr *a;
- int i;
- int32 v;
-
- a = va_arg(fp->args, Addr*);
- if(a == A) {
- sprint(str, "<nil>");
- goto conv;
- }
- i = a->type;
- switch(i) {
-
- default:
- sprint(str, "GOK-type(%d)", a->type);
- break;
-
- case D_NONE:
- str[0] = 0;
- if(a->name != D_NONE || a->reg != NREG || a->sym != S)
- sprint(str, "%M(R%d)(NONE)", a, a->reg);
- break;
-
- case D_CONST:
- if(a->reg != NREG)
- sprint(str, "$%M(R%d)", a, a->reg);
- else
- sprint(str, "$%M", a);
- break;
-
- case D_CONST2:
- sprint(str, "$%d-%d", a->offset, a->offset2);
- break;
-
- case D_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 != NREG)
- sprint(str+strlen(str), "(R%d)", a->reg);
- break;
-
- case D_OCONST:
- sprint(str, "$*$%M", a);
- if(a->reg != NREG)
- sprint(str, "%M(R%d)(CONST)", a, a->reg);
- break;
-
- case D_OREG:
- if(a->reg != NREG)
- sprint(str, "%M(R%d)", a, a->reg);
- else
- sprint(str, "%M", a);
- break;
-
- case D_REG:
- sprint(str, "R%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_REGREG:
- sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_REGREG2:
- sprint(str, "R%d,R%d", a->reg, (int)a->offset);
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_FREG:
- sprint(str, "F%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_BRANCH:
- if(a->u.branch == P || a->u.branch->loc == 0) {
- if(a->sym != S)
- sprint(str, "%s+%d(APC)", a->sym->name, a->offset);
- else
- sprint(str, "%d(APC)", a->offset);
- } else
- if(a->sym != S)
- sprint(str, "%s+%d(APC)", a->sym->name, a->u.branch->loc);
- else
- sprint(str, "%d(APC)", a->u.branch->loc);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
- break;
-
- // TODO(kaib): Add back
-// case D_ADDR:
-// a->type = a->index;
-// a->index = D_NONE;
-// snprint(str, sizeof(str), "$%D", a);
-// a->index = a->type;
-// a->type = D_ADDR;
-// goto conv;
- }
-conv:
- fmtstrcpy(fp, str);
- if(a->gotype)
- fmtprint(fp, "{%s}", a->gotype->name);
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-char* strcond[16] =
-{
- ".EQ",
- ".NE",
- ".HS",
- ".LO",
- ".MI",
- ".PL",
- ".VS",
- ".VC",
- ".HI",
- ".LS",
- ".GE",
- ".LT",
- ".GT",
- ".LE",
- "",
- ".NV"
-};
-
-int
-Cconv(Fmt *fp)
-{
- char s[STRINGSZ];
- int c;
-
- c = va_arg(fp->args, int);
- strcpy(s, strcond[c & C_SCOND]);
- if(c & C_SBIT)
- strcat(s, ".S");
- if(c & C_PBIT)
- strcat(s, ".P");
- if(c & C_WBIT)
- strcat(s, ".W");
- if(c & C_UBIT) /* ambiguous with FBIT */
- strcat(s, ".U");
- return fmtstrcpy(fp, s);
-}
-
-int
-Yconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sconsize; 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);
-}
-
-int
-Rconv(Fmt *fp)
-{
- int r;
- char str[STRINGSZ];
-
- r = va_arg(fp->args, int);
- snprint(str, sizeof(str), "R%d", r);
- return fmtstrcpy(fp, str);
-}
-
-int
-Mconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Addr *a;
-
- a = va_arg(fp->args, Addr*);
- switch(a->name) {
- default:
- snprint(str, sizeof(str), "GOK-name(%d)", a->name);
- break;
-
- case D_NONE:
- snprint(str, sizeof(str), "%d", a->offset);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
- break;
- }
- return fmtstrcpy(fp, str);
-}
diff --git a/src/cmd/5g/opt.h b/src/cmd/5g/opt.h
index 15b9d1458..e3e3f78ed 100644
--- a/src/cmd/5g/opt.h
+++ b/src/cmd/5g/opt.h
@@ -96,6 +96,7 @@ EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
+EXTERN Bits ivar;
EXTERN Bits ovar;
EXTERN int change;
EXTERN int32 maxnr;
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index c78fb3d1c..4aa645206 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -287,6 +287,8 @@ subprop(Flow *r0)
if(uniqs(r) == nil)
break;
p = r->prog;
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ continue;
proginfo(&info, p);
if(info.flags & Call)
return 0;
@@ -397,7 +399,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
if(debug['P'])
print("; merge; f=%d", f);
}
- t = copyu(p, v2, A);
+ t = copyu(p, v2, nil);
switch(t) {
case 2: /* rar, can't split */
if(debug['P'])
@@ -435,7 +437,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
break;
}
if(!f) {
- t = copyu(p, v1, A);
+ t = copyu(p, v1, nil);
if(!f && (t == 2 || t == 3 || t == 4)) {
f = 1;
if(debug['P'])
@@ -479,7 +481,7 @@ constprop(Adr *c1, Adr *v1, Flow *r)
if(debug['P'])
print("; sub%D/%D", &p->from, v1);
p->from = *v1;
- } else if(copyu(p, v1, A) > 1) {
+ } else if(copyu(p, v1, nil) > 1) {
if(debug['P'])
print("; %Dset; return\n", v1);
return;
@@ -592,10 +594,10 @@ shiftprop(Flow *r)
p1 = r1->prog;
if(debug['P'])
print("\n%P", p1);
- switch(copyu(p1, &p->to, A)) {
+ switch(copyu(p1, &p->to, nil)) {
case 0: /* not used or set */
- if((p->from.type == D_REG && copyu(p1, &p->from, A) > 1) ||
- (a.type == D_REG && copyu(p1, &a, A) > 1))
+ if((p->from.type == D_REG && copyu(p1, &p->from, nil) > 1) ||
+ (a.type == D_REG && copyu(p1, &a, nil) > 1))
FAIL("args modified");
continue;
case 3: /* set, not used */
@@ -663,7 +665,7 @@ shiftprop(Flow *r)
p1 = r1->prog;
if(debug['P'])
print("\n%P", p1);
- switch(copyu(p1, &p->to, A)) {
+ switch(copyu(p1, &p->to, nil)) {
case 0: /* not used or set */
continue;
case 3: /* set, not used */
@@ -719,7 +721,7 @@ findpre(Flow *r, Adr *v)
for(r1=uniqp(r); r1!=nil; r=r1,r1=uniqp(r)) {
if(uniqs(r1) != r)
return nil;
- switch(copyu(r1->prog, v, A)) {
+ switch(copyu(r1->prog, v, nil)) {
case 1: /* used */
case 2: /* read-alter-rewrite */
return nil;
@@ -745,7 +747,7 @@ findinc(Flow *r, Flow *r2, Adr *v)
for(r1=uniqs(r); r1!=nil && r1!=r2; r=r1,r1=uniqs(r)) {
if(uniqp(r1) != r)
return nil;
- switch(copyu(r1->prog, v, A)) {
+ switch(copyu(r1->prog, v, nil)) {
case 0: /* not touched */
continue;
case 4: /* set and used */
@@ -787,7 +789,7 @@ nochange(Flow *r, Flow *r2, Prog *p)
for(; r!=nil && r!=r2; r=uniqs(r)) {
p = r->prog;
for(i=0; i<n; i++)
- if(copyu(p, &a[i], A) > 1)
+ if(copyu(p, &a[i], nil) > 1)
return 0;
}
return 1;
@@ -800,7 +802,7 @@ findu1(Flow *r, Adr *v)
if(r->active)
return 0;
r->active = 1;
- switch(copyu(r->prog, v, A)) {
+ switch(copyu(r->prog, v, nil)) {
case 1: /* used */
case 2: /* read-alter-rewrite */
case 4: /* set and used */
@@ -943,7 +945,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(v->type != D_REG)
return 0;
if(p->from.type == D_CONST) { /* read reglist, read/rar */
- if(s != A) {
+ if(s != nil) {
if(p->from.offset&(1<<v->reg))
return 1;
if(copysub(&p->to, v, s, 1))
@@ -958,7 +960,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(p->from.offset&(1<<v->reg))
return 1;
} else { /* read/rar, write reglist */
- if(s != A) {
+ if(s != nil) {
if(p->to.offset&(1<<v->reg))
return 1;
if(copysub(&p->from, v, s, 1))
@@ -1003,7 +1005,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 2;
}
}
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->from, v, s, 1))
return 1;
if(!copyas(&p->to, v))
@@ -1063,7 +1065,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ACMN:
case ACASE:
case ATST: /* read,, */
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->from, v, s, 1))
return 1;
if(copysub1(p, v, s, 1))
@@ -1108,7 +1110,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ABLT:
case ABGT:
case ABLE:
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->from, v, s, 1))
return 1;
return copysub1(p, v, s, 1);
@@ -1120,7 +1122,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
case AB: /* funny */
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
@@ -1130,7 +1132,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
case ARET: /* funny */
- if(s != A)
+ if(s != nil)
return 1;
return 3;
@@ -1138,7 +1140,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(v->type == D_REG) {
if(v->reg <= REGEXT && v->reg > exregoffset)
return 2;
- if(v->reg == (uchar)REGARG)
+ if(v->reg == REGARG)
return 2;
}
if(v->type == D_FREG)
@@ -1147,7 +1149,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(p->from.type == D_REG && v->type == D_REG && p->from.reg == v->reg)
return 2;
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
@@ -1155,15 +1157,37 @@ copyu(Prog *p, Adr *v, Adr *s)
if(copyau(&p->to, v))
return 4;
return 3;
-
+ case ADUFFZERO:
+ // R0 is zero, used by DUFFZERO, cannot be substituted.
+ // R1 is ptr to memory, used and set, cannot be substituted.
+ if(v->type == D_REG) {
+ if(v->reg == REGALLOC_R0)
+ return 1;
+ if(v->reg == REGALLOC_R0+1)
+ return 2;
+ }
+ return 0;
+ case ADUFFCOPY:
+ // R0 is scratch, set by DUFFCOPY, cannot be substituted.
+ // R1, R2 areptr to src, dst, used and set, cannot be substituted.
+ if(v->type == D_REG) {
+ if(v->reg == REGALLOC_R0)
+ return 3;
+ if(v->reg == REGALLOC_R0+1 || v->reg == REGALLOC_R0+2)
+ return 2;
+ }
+ return 0;
+
case ATEXT: /* funny */
if(v->type == D_REG)
- if(v->reg == (uchar)REGARG)
+ if(v->reg == REGARG)
return 3;
return 0;
case APCDATA:
case AFUNCDATA:
+ case AVARDEF:
+ case AVARKILL:
return 0;
}
}
@@ -1241,35 +1265,79 @@ copyau(Adr *a, Adr *v)
return 0;
}
+static int
+a2type(Prog *p)
+{
+ if(p->reg == NREG)
+ return D_NONE;
+
+ switch(p->as) {
+ default:
+ fatal("a2type: unhandled %P", p);
+
+ case AAND:
+ case AEOR:
+ case ASUB:
+ case ARSB:
+ case AADD:
+ case AADC:
+ case ASBC:
+ case ARSC:
+ case ATST:
+ case ATEQ:
+ case ACMP:
+ case ACMN:
+ case AORR:
+ case ABIC:
+ case AMVN:
+ case ASRL:
+ case ASRA:
+ case ASLL:
+ case AMULU:
+ case ADIVU:
+ case AMUL:
+ case ADIV:
+ case AMOD:
+ case AMODU:
+ case AMULA:
+ case AMULL:
+ case AMULAL:
+ case AMULLU:
+ case AMULALU:
+ case AMULWT:
+ case AMULWB:
+ case AMULAWT:
+ case AMULAWB:
+ return D_REG;
+
+ 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:
+ return D_FREG;
+ }
+}
+
/*
* compare v to the center
* register in p (p->reg)
- * the trick is that this
- * register might be D_REG
- * D_FREG. there are basically
- * two cases,
- * ADD r,r,r
- * CMP r,r,
*/
static int
copyau1(Prog *p, Adr *v)
{
-
- if(regtyp(v))
- if(p->reg == v->reg) {
- if(p->to.type != D_NONE) {
- if(v->type == p->to.type)
- return 1;
- return 0;
- }
- if(p->from.type != D_NONE) {
- if(v->type == p->from.type)
- return 1;
- return 0;
- }
- print("copyau1: can't tell %P\n", p);
- }
- return 0;
+ if(v->type == D_REG && v->reg == NREG)
+ return 0;
+ return p->reg == v->reg && a2type(p) == v->type;
}
/*
diff --git a/src/cmd/5g/prog.c b/src/cmd/5g/prog.c
index 5aa6163d8..797bc0718 100644
--- a/src/cmd/5g/prog.c
+++ b/src/cmd/5g/prog.c
@@ -26,9 +26,11 @@ static ProgInfo progtable[ALAST] = {
[ATEXT]= {Pseudo},
[AFUNCDATA]= {Pseudo},
[APCDATA]= {Pseudo},
- [AUNDEF]= {OK},
+ [AUNDEF]= {Break},
[AUSEFIELD]= {OK},
[ACHECKNIL]= {LeftRead},
+ [AVARDEF]= {Pseudo | RightWrite},
+ [AVARKILL]= {Pseudo | RightWrite},
// NOP is an internal no-op that also stands
// for USED and SET annotations, not the Intel opcode.
@@ -91,6 +93,12 @@ static ProgInfo progtable[ALAST] = {
[AMOVF]= {SizeF | LeftRead | RightWrite | Move},
[AMOVH]= {SizeW | LeftRead | RightWrite | Move},
[AMOVW]= {SizeL | LeftRead | RightWrite | Move},
+ // In addtion, duffzero reads R0,R1 and writes R1. This fact is
+ // encoded in peep.c
+ [ADUFFZERO]= {Call},
+ // In addtion, duffcopy reads R1,R2 and writes R0,R1,R2. This fact is
+ // encoded in peep.c
+ [ADUFFCOPY]= {Call},
// These should be split into the two different conversions instead
// of overloading the one.
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c
index d2a8cc488..4762df506 100644
--- a/src/cmd/5g/reg.c
+++ b/src/cmd/5g/reg.c
@@ -56,30 +56,6 @@ rcmp(const void *a1, const void *a2)
return p2->varno - p1->varno;
}
-static void
-setoutvar(void)
-{
- Type *t;
- Node *n;
- Addr a;
- Iter save;
- Bits bit;
- int z;
-
- t = structfirst(&save, getoutarg(curfn->type));
- while(t != T) {
- n = nodarg(t, 1);
- a = zprog.from;
- naddr(n, &a, 0);
- bit = mkvar(R, &a);
- for(z=0; z<BITS; z++)
- ovar.b[z] |= bit.b[z];
- t = structnext(&save);
- }
-//if(bany(&ovar))
-//print("ovar = %Q\n", ovar);
-}
-
void
excise(Flow *r)
{
@@ -153,13 +129,15 @@ static char* regname[] = {
static Node* regnodes[NREGVAR];
+static void walkvardef(Node *n, Reg *r, int active);
+
void
regopt(Prog *firstp)
{
Reg *r, *r1;
Prog *p;
Graph *g;
- int i, z;
+ int i, z, active;
uint32 vreg;
Bits bit;
ProgInfo info;
@@ -168,8 +146,7 @@ regopt(Prog *firstp)
fmtinstall('Q', Qconv);
first = 0;
}
-
- fixjmp(firstp);
+
mergetemp(firstp);
/*
@@ -191,12 +168,10 @@ regopt(Prog *firstp)
params.b[z] = 0;
consts.b[z] = 0;
addrs.b[z] = 0;
+ ivar.b[z] = 0;
ovar.b[z] = 0;
}
- // build list of return variables
- setoutvar();
-
/*
* pass 1
* build aux data structure
@@ -204,12 +179,18 @@ regopt(Prog *firstp)
* find use and set of variables
*/
g = flowstart(firstp, sizeof(Reg));
- if(g == nil)
+ if(g == nil) {
+ for(i=0; i<nvar; i++)
+ var[i].node->opt = nil;
return;
+ }
+
firstr = (Reg*)g->start;
for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog;
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ continue;
proginfo(&info, p);
// Avoid making variables for direct-called functions.
@@ -271,6 +252,26 @@ regopt(Prog *firstp)
dumpit("pass2", &firstr->f, 1);
/*
+ * pass 2.5
+ * iterate propagating fat vardef covering forward
+ * r->act records vars with a VARDEF since the last CALL.
+ * (r->act will be reused in pass 5 for something else,
+ * but we'll be done with it by then.)
+ */
+ active = 0;
+ for(r = firstr; r != R; r = (Reg*)r->f.link) {
+ r->f.active = 0;
+ r->act = zbits;
+ }
+ for(r = firstr; r != R; r = (Reg*)r->f.link) {
+ p = r->f.prog;
+ if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) {
+ active++;
+ walkvardef(p->to.node, r, active);
+ }
+ }
+
+ /*
* pass 3
* iterate propagating usage
* back until flow graph is complete
@@ -471,6 +472,14 @@ brk:
dumpit("pass6", &firstr->f, 1);
/*
+ * free aux structures. peep allocates new ones.
+ */
+ for(i=0; i<nvar; i++)
+ var[i].node->opt = nil;
+ flowend(g);
+ firstr = R;
+
+ /*
* pass 7
* peep-hole on basic block
*/
@@ -523,20 +532,44 @@ brk:
}
if(p->as == AMOVW && vreg != 0) {
- if(p->from.sym != S)
+ if(p->from.sym != nil)
if(p->from.name == D_AUTO || p->from.name == D_PARAM) {
p->from.offset += vreg;
// print("%P adjusting from %d %d\n", p, vreg, p->from.type);
}
- if(p->to.sym != S)
+ if(p->to.sym != nil)
if(p->to.name == D_AUTO || p->to.name == D_PARAM) {
p->to.offset += vreg;
// print("%P adjusting to %d %d\n", p, vreg, p->from.type);
}
}
}
+}
- flowend(g);
+static void
+walkvardef(Node *n, Reg *r, int active)
+{
+ Reg *r1, *r2;
+ int bn;
+ Var *v;
+
+ for(r1=r; r1!=R; r1=(Reg*)r1->f.s1) {
+ if(r1->f.active == active)
+ break;
+ r1->f.active = active;
+ if(r1->f.prog->as == AVARKILL && r1->f.prog->to.node == n)
+ break;
+ for(v=n->opt; v!=nil; v=v->nextinnode) {
+ bn = v - var;
+ r1->act.b[bn/32] |= 1L << (bn%32);
+ }
+ if(r1->f.prog->as == ABL)
+ break;
+ }
+
+ for(r2=r; r2!=r1; r2=(Reg*)r2->f.s1)
+ if(r2->f.s2 != nil)
+ walkvardef(n, (Reg*)r2->f.s2, active);
}
void
@@ -551,6 +584,10 @@ addsplits(void)
continue;
if(r->f.prog->as == ABL)
continue;
+ if(r->f.prog->as == ADUFFZERO)
+ continue;
+ if(r->f.prog->as == ADUFFCOPY)
+ continue;
for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link) {
if(r1->f.loop <= 1)
continue;
@@ -596,11 +633,11 @@ addmove(Reg *r, int bn, int rn, int f)
a = &p1->to;
a->name = v->name;
a->node = v->node;
- a->sym = v->node->sym;
+ a->sym = linksym(v->node->sym);
a->offset = v->offset;
a->etype = v->etype;
a->type = D_OREG;
- if(a->etype == TARRAY || a->sym == S)
+ if(a->etype == TARRAY || a->sym == nil)
a->type = D_CONST;
if(v->addr)
@@ -790,6 +827,16 @@ mkvar(Reg *r, Adr *a)
if(nvar >= NVAR) {
if(debug['w'] > 1 && node)
fatal("variable not optimized: %D", a);
+
+ // If we're not tracking a word in a variable, mark the rest as
+ // having its address taken, so that we keep the whole thing
+ // live at all calls. otherwise we might optimize away part of
+ // a variable but not all of it.
+ for(i=0; i<nvar; i++) {
+ v = var+i;
+ if(v->node == node)
+ v->addr = 1;
+ }
goto none;
}
@@ -804,9 +851,13 @@ mkvar(Reg *r, Adr *a)
v->addr = flag; // funny punning
v->node = node;
- if(debug['R'])
- print("bit=%2d et=%2E w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
-
+ // node->opt is the head of a linked list
+ // of Vars within the given Node, so that
+ // we can start at a Var and find all the other
+ // Vars in the same Go variable.
+ v->nextinnode = node->opt;
+ node->opt = v;
+
bit = blsh(i);
if(n == D_EXTERN || n == D_STATIC)
for(z=0; z<BITS; z++)
@@ -815,6 +866,45 @@ mkvar(Reg *r, Adr *a)
for(z=0; z<BITS; z++)
params.b[z] |= bit.b[z];
+ if(node->class == PPARAM)
+ for(z=0; z<BITS; z++)
+ ivar.b[z] |= bit.b[z];
+ if(node->class == PPARAMOUT)
+ for(z=0; z<BITS; z++)
+ ovar.b[z] |= bit.b[z];
+
+ // Treat values with their address taken as live at calls,
+ // because the garbage collector's liveness analysis in ../gc/plive.c does.
+ // These must be consistent or else we will elide stores and the garbage
+ // collector will see uninitialized data.
+ // The typical case where our own analysis is out of sync is when the
+ // node appears to have its address taken but that code doesn't actually
+ // get generated and therefore doesn't show up as an address being
+ // taken when we analyze the instruction stream.
+ // One instance of this case is when a closure uses the same name as
+ // an outer variable for one of its own variables declared with :=.
+ // The parser flags the outer variable as possibly shared, and therefore
+ // sets addrtaken, even though it ends up not being actually shared.
+ // If we were better about _ elision, _ = &x would suffice too.
+ // The broader := in a closure problem is mentioned in a comment in
+ // closure.c:/^typecheckclosure and dcl.c:/^oldname.
+ if(node->addrtaken)
+ v->addr = 1;
+
+ // Disable registerization for globals, because:
+ // (1) we might panic at any time and we want the recovery code
+ // to see the latest values (issue 1304).
+ // (2) we don't know what pointers might point at them and we want
+ // loads via those pointers to see updated values and vice versa (issue 7995).
+ //
+ // Disable registerization for results if using defer, because the deferred func
+ // might recover and return, causing the current values to be used.
+ if(node->class == PEXTERN || (hasdefer && node->class == PPARAMOUT))
+ v->addr = 1;
+
+ if(debug['R'])
+ print("bit=%2d et=%2E w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
+
return bit;
none:
@@ -825,7 +915,8 @@ void
prop(Reg *r, Bits ref, Bits cal)
{
Reg *r1, *r2;
- int z;
+ int z, i, j;
+ Var *v, *v1;
for(r1 = r; r1 != R; r1 = (Reg*)r1->f.p1) {
for(z=0; z<BITS; z++) {
@@ -844,10 +935,61 @@ prop(Reg *r, Bits ref, Bits cal)
case ABL:
if(noreturn(r1->f.prog))
break;
+
+ // Mark all input variables (ivar) as used, because that's what the
+ // liveness bitmaps say. The liveness bitmaps say that so that a
+ // panic will not show stale values in the parameter dump.
+ // Mark variables with a recent VARDEF (r1->act) as used,
+ // so that the optimizer flushes initializations to memory,
+ // so that if a garbage collection happens during this CALL,
+ // the collector will see initialized memory. Again this is to
+ // match what the liveness bitmaps say.
for(z=0; z<BITS; z++) {
- cal.b[z] |= ref.b[z] | externs.b[z];
+ cal.b[z] |= ref.b[z] | externs.b[z] | ivar.b[z] | r1->act.b[z];
ref.b[z] = 0;
}
+
+ // cal.b is the current approximation of what's live across the call.
+ // Every bit in cal.b is a single stack word. For each such word,
+ // find all the other tracked stack words in the same Go variable
+ // (struct/slice/string/interface) and mark them live too.
+ // This is necessary because the liveness analysis for the garbage
+ // collector works at variable granularity, not at word granularity.
+ // It is fundamental for slice/string/interface: the garbage collector
+ // needs the whole value, not just some of the words, in order to
+ // interpret the other bits correctly. Specifically, slice needs a consistent
+ // ptr and cap, string needs a consistent ptr and len, and interface
+ // needs a consistent type word and data word.
+ for(z=0; z<BITS; z++) {
+ if(cal.b[z] == 0)
+ continue;
+ for(i=0; i<32; i++) {
+ if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0)
+ continue;
+ v = var+z*32+i;
+ if(v->node->opt == nil) // v represents fixed register, not Go variable
+ continue;
+
+ // v->node->opt is the head of a linked list of Vars
+ // corresponding to tracked words from the Go variable v->node.
+ // Walk the list and set all the bits.
+ // For a large struct this could end up being quadratic:
+ // after the first setting, the outer loop (for z, i) would see a 1 bit
+ // for all of the remaining words in the struct, and for each such
+ // word would go through and turn on all the bits again.
+ // To avoid the quadratic behavior, we only turn on the bits if
+ // v is the head of the list or if the head's bit is not yet turned on.
+ // This will set the bits at most twice, keeping the overall loop linear.
+ v1 = v->node->opt;
+ j = v1 - var;
+ if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
+ for(; v1 != nil; v1 = v1->nextinnode) {
+ j = v1 - var;
+ cal.b[j/32] |= 1<<(j&31);
+ }
+ }
+ }
+ }
break;
case ATEXT:
@@ -863,17 +1005,6 @@ prop(Reg *r, Bits ref, Bits cal)
ref.b[z] = 0;
}
break;
-
- default:
- // Work around for issue 1304:
- // flush modified globals before each instruction.
- for(z=0; z<BITS; z++) {
- cal.b[z] |= externs.b[z];
- // issue 4066: flush modified return variables in case of panic
- if(hasdefer)
- cal.b[z] |= ovar.b[z];
- }
- break;
}
for(z=0; z<BITS; z++) {
ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
@@ -1004,18 +1135,20 @@ paint1(Reg *r, int bn)
r->act.b[z] |= bb;
p = r->f.prog;
- if(r->use1.b[z] & bb) {
- change += CREF * r->f.loop;
- if(debug['R'] > 1)
- print("%d%P\tu1 %Q $%d\n", r->f.loop,
- p, blsh(bn), change);
- }
- if((r->use2.b[z]|r->set.b[z]) & bb) {
- change += CREF * r->f.loop;
- if(debug['R'] > 1)
- print("%d%P\tu2 %Q $%d\n", r->f.loop,
- p, blsh(bn), change);
+ if(r->f.prog->as != ANOP) { // don't give credit for NOPs
+ if(r->use1.b[z] & bb) {
+ change += CREF * r->f.loop;
+ if(debug['R'] > 1)
+ print("%d%P\tu1 %Q $%d\n", r->f.loop,
+ p, blsh(bn), change);
+ }
+ if((r->use2.b[z]|r->set.b[z]) & bb) {
+ change += CREF * r->f.loop;
+ if(debug['R'] > 1)
+ print("%d%P\tu2 %Q $%d\n", r->f.loop,
+ p, blsh(bn), change);
+ }
}
if(STORE(r) & r->regdiff.b[z] & bb) {
@@ -1172,7 +1305,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
void
addreg(Adr *a, int rn)
{
- a->sym = 0;
+ a->sym = nil;
a->name = D_NONE;
a->type = D_REG;
a->reg = rn;
@@ -1292,9 +1425,9 @@ dumpit(char *str, Flow *r0, int isreg)
if(r1 != nil) {
print(" pred:");
for(; r1 != nil; r1 = r1->p2link)
- print(" %.4ud", r1->prog->loc);
+ print(" %.4ud", (int)r1->prog->pc);
if(r->p1 != nil)
- print(" (and %.4ud)", r->p1->prog->loc);
+ print(" (and %.4ud)", (int)r->p1->prog->pc);
else
print(" (only)");
print("\n");
@@ -1303,7 +1436,7 @@ dumpit(char *str, Flow *r0, int isreg)
// if(r1 != nil) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4ud", r1->prog->loc);
+// print(" %.4ud", (int)r1->prog->pc);
// print("\n");
// }
}
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h
index e8cf83ddd..9e8aceecb 100644
--- a/src/cmd/5l/5.out.h
+++ b/src/cmd/5l/5.out.h
@@ -198,6 +198,12 @@ enum as
AFUNCDATA,
APCDATA,
ACHECKNIL,
+ AVARDEF,
+ AVARKILL,
+ ADUFFCOPY,
+ ADUFFZERO,
+
+ AMRC, // MRC/MCR
ALAST,
};
@@ -233,62 +239,43 @@ enum as
#define SHIFT_AR 2<<5
#define SHIFT_RR 3<<5
+enum
+{
/* type/name */
-#define D_GOK 0
-#define D_NONE 1
+ D_GOK = 0,
+ D_NONE = 1,
/* type */
-#define D_BRANCH (D_NONE+1)
-#define D_OREG (D_NONE+2)
-#define D_CONST (D_NONE+7)
-#define D_FCONST (D_NONE+8)
-#define D_SCONST (D_NONE+9)
-#define D_PSR (D_NONE+10)
-#define D_REG (D_NONE+12)
-#define D_FREG (D_NONE+13)
-#define D_FILE (D_NONE+16)
-#define D_OCONST (D_NONE+17)
-#define D_FILE1 (D_NONE+18)
-
-#define D_SHIFT (D_NONE+19)
-#define D_FPCR (D_NONE+20)
-#define D_REGREG (D_NONE+21) // (reg, reg)
-#define D_ADDR (D_NONE+22)
-
-#define D_SBIG (D_NONE+23)
-#define D_CONST2 (D_NONE+24)
-
-#define D_REGREG2 (D_NONE+25) // reg, reg
+ D_BRANCH = (D_NONE+1),
+ D_OREG = (D_NONE+2),
+ D_CONST = (D_NONE+7),
+ D_FCONST = (D_NONE+8),
+ D_SCONST = (D_NONE+9),
+ D_PSR = (D_NONE+10),
+ D_REG = (D_NONE+12),
+ D_FREG = (D_NONE+13),
+ D_FILE = (D_NONE+16),
+ D_OCONST = (D_NONE+17),
+ D_FILE1 = (D_NONE+18),
+
+ D_SHIFT = (D_NONE+19),
+ D_FPCR = (D_NONE+20),
+ D_REGREG = (D_NONE+21), // (reg, reg)
+ D_ADDR = (D_NONE+22),
+
+ D_SBIG = (D_NONE+23),
+ D_CONST2 = (D_NONE+24),
+
+ D_REGREG2 = (D_NONE+25), // reg, reg
/* name */
-#define D_EXTERN (D_NONE+3)
-#define D_STATIC (D_NONE+4)
-#define D_AUTO (D_NONE+5)
-#define D_PARAM (D_NONE+6)
-
-/* internal only */
-#define D_SIZE (D_NONE+40)
-#define D_PCREL (D_NONE+41)
-#define D_GOTOFF (D_NONE+42) // R_ARM_GOTOFF
-#define D_PLT0 (D_NONE+43) // R_ARM_PLT32, 1st inst: add ip, pc, #0xNN00000
-#define D_PLT1 (D_NONE+44) // R_ARM_PLT32, 2nd inst: add ip, ip, #0xNN000
-#define D_PLT2 (D_NONE+45) // R_ARM_PLT32, 3rd inst: ldr pc, [ip, #0xNNN]!
-#define D_CALL (D_NONE+46) // R_ARM_PLT32/R_ARM_CALL/R_ARM_JUMP24, bl xxxxx or b yyyyy
-#define D_TLS (D_NONE+47) // R_ARM_TLS_LE32
+ D_EXTERN = (D_NONE+3),
+ D_STATIC = (D_NONE+4),
+ D_AUTO = (D_NONE+5),
+ D_PARAM = (D_NONE+6),
+};
/*
* this is the ranlib header
*/
#define SYMDEF "__.GOSYMDEF"
-
-/*
- * this is the simulated IEEE floating point
- */
-typedef struct ieee Ieee;
-struct ieee
-{
- int32 l; /* contains ls-man 0xffffffff */
- int32 h; /* contains sign 0x80000000
- exp 0x7ff00000
- ms-man 0x000fffff */
-};
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c
index 33cdf8096..5e9267b5b 100644
--- a/src/cmd/5l/asm.c
+++ b/src/cmd/5l/asm.c
@@ -35,43 +35,26 @@
#include "../ld/elf.h"
#include "../ld/dwarf.h"
-static Prog *PP;
char linuxdynld[] = "/lib/ld-linux.so.3"; // 2 for OABI, 3 for EABI
char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
char openbsddynld[] = "XXX";
char netbsddynld[] = "/libexec/ld.elf_so";
char dragonflydynld[] = "XXX";
-
-int32
-entryvalue(void)
-{
- char *a;
- Sym *s;
-
- a = INITENTRY;
- if(*a >= '0' && *a <= '9')
- return atolwhex(a);
- s = lookup(a, 0);
- if(s->type == 0)
- return INITTEXT;
- if(s->type != STEXT)
- diag("entry not text: %s", s->name);
- return s->value;
-}
+char solarisdynld[] = "XXX";
static int
needlib(char *name)
{
char *p;
- Sym *s;
+ LSym *s;
if(*name == '\0')
return 0;
/* reuse hash code in symbol table */
p = smprint(".dynlib.%s", name);
- s = lookup(p, 0);
+ s = linklookup(ctxt, p, 0);
free(p);
if(s->type == 0) {
s->type = 100; // avoid SDATA, etc.
@@ -82,9 +65,9 @@ needlib(char *name)
int nelfsym = 1;
-static void addpltsym(Sym*);
-static void addgotsym(Sym*);
-static void addgotsyminternal(Sym*);
+static void addpltsym(Link*, LSym*);
+static void addgotsym(Link*, LSym*);
+static void addgotsyminternal(Link*, LSym*);
// Preserve highest 8 bits of a, and do addition to lower 24-bit
// of a and b; used to adjust ARM branch intruction's target
@@ -95,19 +78,19 @@ braddoff(int32 a, int32 b)
}
void
-adddynrela(Sym *rel, Sym *s, Reloc *r)
+adddynrela(LSym *rel, LSym *s, Reloc *r)
{
- addaddrplus(rel, s, r->off);
- adduint32(rel, R_ARM_RELATIVE);
+ addaddrplus(ctxt, rel, s, r->off);
+ adduint32(ctxt, rel, R_ARM_RELATIVE);
}
void
-adddynrel(Sym *s, Reloc *r)
+adddynrel(LSym *s, Reloc *r)
{
- Sym *targ, *rel;
+ LSym *targ, *rel;
targ = r->sym;
- cursym = s;
+ ctxt->cursym = s;
switch(r->type) {
default:
@@ -119,10 +102,10 @@ adddynrel(Sym *s, Reloc *r)
// Handle relocations found in ELF object files.
case 256 + R_ARM_PLT32:
- r->type = D_CALL;
+ r->type = R_CALLARM;
if(targ->type == SDYNIMPORT) {
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = braddoff(r->add, targ->plt / 4);
}
return;
@@ -134,54 +117,54 @@ adddynrel(Sym *s, Reloc *r)
case 256 + R_ARM_GOT32: // R_ARM_GOT_BREL
if(targ->type != SDYNIMPORT) {
- addgotsyminternal(targ);
+ addgotsyminternal(ctxt, targ);
} else {
- addgotsym(targ);
+ addgotsym(ctxt, targ);
}
- r->type = D_CONST; // write r->add during relocsym
+ r->type = R_CONST; // write r->add during relocsym
r->sym = S;
r->add += targ->got;
return;
case 256 + R_ARM_GOT_PREL: // GOT(S) + A - P
if(targ->type != SDYNIMPORT) {
- addgotsyminternal(targ);
+ addgotsyminternal(ctxt, targ);
} else {
- addgotsym(targ);
+ addgotsym(ctxt, targ);
}
- r->type = D_PCREL;
- r->sym = lookup(".got", 0);
+ r->type = R_PCREL;
+ r->sym = linklookup(ctxt, ".got", 0);
r->add += targ->got + 4;
return;
case 256 + R_ARM_GOTOFF: // R_ARM_GOTOFF32
- r->type = D_GOTOFF;
+ r->type = R_GOTOFF;
return;
case 256 + R_ARM_GOTPC: // R_ARM_BASE_PREL
- r->type = D_PCREL;
- r->sym = lookup(".got", 0);
+ r->type = R_PCREL;
+ r->sym = linklookup(ctxt, ".got", 0);
r->add += 4;
return;
case 256 + R_ARM_CALL:
- r->type = D_CALL;
+ r->type = R_CALLARM;
if(targ->type == SDYNIMPORT) {
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = braddoff(r->add, targ->plt / 4);
}
return;
case 256 + R_ARM_REL32: // R_ARM_REL32
- r->type = D_PCREL;
+ r->type = R_PCREL;
r->add += 4;
return;
case 256 + R_ARM_ABS32:
if(targ->type == SDYNIMPORT)
diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ->name);
- r->type = D_ADDR;
+ r->type = R_ADDR;
return;
case 256 + R_ARM_V4BX:
@@ -195,10 +178,10 @@ adddynrel(Sym *s, Reloc *r)
case 256 + R_ARM_PC24:
case 256 + R_ARM_JUMP24:
- r->type = D_CALL;
+ r->type = R_CALLARM;
if(targ->type == SDYNIMPORT) {
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = braddoff(r->add, targ->plt / 4);
}
return;
@@ -209,28 +192,28 @@ adddynrel(Sym *s, Reloc *r)
return;
switch(r->type) {
- case D_PCREL:
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ case R_CALLARM:
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = targ->plt;
return;
- case D_ADDR:
+ case R_ADDR:
if(s->type != SDATA)
break;
if(iself) {
- adddynsym(targ);
- rel = lookup(".rel", 0);
- addaddrplus(rel, s, r->off);
- adduint32(rel, ELF32_R_INFO(targ->dynid, R_ARM_GLOB_DAT)); // we need a S + A dynmic reloc
- r->type = D_CONST; // write r->add during relocsym
+ adddynsym(ctxt, targ);
+ rel = linklookup(ctxt, ".rel", 0);
+ addaddrplus(ctxt, rel, s, r->off);
+ adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_ARM_GLOB_DAT)); // we need a S + A dynmic reloc
+ r->type = R_CONST; // write r->add during relocsym
r->sym = S;
return;
}
break;
}
- cursym = s;
+ ctxt->cursym = s;
diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
}
@@ -246,21 +229,21 @@ elfreloc1(Reloc *r, vlong sectoff)
default:
return -1;
- case D_ADDR:
+ case R_ADDR:
if(r->siz == 4)
LPUT(R_ARM_ABS32 | elfsym<<8);
else
return -1;
break;
- case D_PCREL:
+ case R_PCREL:
if(r->siz == 4)
LPUT(R_ARM_REL32 | elfsym<<8);
else
return -1;
break;
- case D_CALL:
+ case R_CALLARM:
if(r->siz == 4) {
if((r->add & 0xff000000) == 0xeb000000) // BL
LPUT(R_ARM_CALL | elfsym<<8);
@@ -270,7 +253,7 @@ elfreloc1(Reloc *r, vlong sectoff)
return -1;
break;
- case D_TLS:
+ case R_TLS:
if(r->siz == 4) {
if(flag_shared)
LPUT(R_ARM_TLS_IE32 | elfsym<<8);
@@ -287,26 +270,26 @@ elfreloc1(Reloc *r, vlong sectoff)
void
elfsetupplt(void)
{
- Sym *plt, *got;
+ LSym *plt, *got;
- plt = lookup(".plt", 0);
- got = lookup(".got.plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
+ got = linklookup(ctxt, ".got.plt", 0);
if(plt->size == 0) {
// str lr, [sp, #-4]!
- adduint32(plt, 0xe52de004);
+ adduint32(ctxt, plt, 0xe52de004);
// ldr lr, [pc, #4]
- adduint32(plt, 0xe59fe004);
+ adduint32(ctxt, plt, 0xe59fe004);
// add lr, pc, lr
- adduint32(plt, 0xe08fe00e);
+ adduint32(ctxt, plt, 0xe08fe00e);
// ldr pc, [lr, #8]!
- adduint32(plt, 0xe5bef008);
+ adduint32(ctxt, plt, 0xe5bef008);
// .word &GLOBAL_OFFSET_TABLE[0] - .
- addpcrelplus(plt, got, 4);
+ addpcrelplus(ctxt, plt, got, 4);
// the first .plt entry requires 3 .plt.got entries
- adduint32(got, 0);
- adduint32(got, 0);
- adduint32(got, 0);
+ adduint32(ctxt, got, 0);
+ adduint32(ctxt, got, 0);
+ adduint32(ctxt, got, 0);
}
}
@@ -321,13 +304,13 @@ machoreloc1(Reloc *r, vlong sectoff)
int
-archreloc(Reloc *r, Sym *s, vlong *val)
+archreloc(Reloc *r, LSym *s, vlong *val)
{
- Sym *rs;
+ LSym *rs;
if(linkmode == LinkExternal) {
switch(r->type) {
- case D_CALL:
+ case R_CALLARM:
r->done = 0;
// set up addend for eventual relocation via outer symbol.
@@ -352,29 +335,29 @@ archreloc(Reloc *r, Sym *s, vlong *val)
return -1;
}
switch(r->type) {
- case D_CONST:
+ case R_CONST:
*val = r->add;
return 0;
- case D_GOTOFF:
- *val = symaddr(r->sym) + r->add - symaddr(lookup(".got", 0));
+ case R_GOTOFF:
+ *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
return 0;
// The following three arch specific relocations are only for generation of
// Linux/ARM ELF's PLT entry (3 assembler instruction)
- case D_PLT0: // add ip, pc, #0xXX00000
- if (symaddr(lookup(".got.plt", 0)) < symaddr(lookup(".plt", 0)))
+ case R_PLT0: // add ip, pc, #0xXX00000
+ if (symaddr(linklookup(ctxt, ".got.plt", 0)) < symaddr(linklookup(ctxt, ".plt", 0)))
diag(".got.plt should be placed after .plt section.");
*val = 0xe28fc600U +
- (0xff & ((uint32)(symaddr(r->sym) - (symaddr(lookup(".plt", 0)) + r->off) + r->add) >> 20));
+ (0xff & ((uint32)(symaddr(r->sym) - (symaddr(linklookup(ctxt, ".plt", 0)) + r->off) + r->add) >> 20));
return 0;
- case D_PLT1: // add ip, ip, #0xYY000
+ case R_PLT1: // add ip, ip, #0xYY000
*val = 0xe28cca00U +
- (0xff & ((uint32)(symaddr(r->sym) - (symaddr(lookup(".plt", 0)) + r->off) + r->add + 4) >> 12));
+ (0xff & ((uint32)(symaddr(r->sym) - (symaddr(linklookup(ctxt, ".plt", 0)) + r->off) + r->add + 4) >> 12));
return 0;
- case D_PLT2: // ldr pc, [ip, #0xZZZ]!
+ case R_PLT2: // ldr pc, [ip, #0xZZZ]!
*val = 0xe5bcf000U +
- (0xfff & (uint32)(symaddr(r->sym) - (symaddr(lookup(".plt", 0)) + r->off) + r->add + 8));
+ (0xfff & (uint32)(symaddr(r->sym) - (symaddr(linklookup(ctxt, ".plt", 0)) + r->off) + r->add + 8));
return 0;
- case D_CALL: // bl XXXXXX or b YYYYYY
+ case R_CALLARM: // bl XXXXXX or b YYYYYY
*val = braddoff((0xff000000U & (uint32)r->add),
(0xffffff & (uint32)
((symaddr(r->sym) + ((uint32)r->add) * 4 - (s->value + r->off)) / 4)));
@@ -384,7 +367,7 @@ archreloc(Reloc *r, Sym *s, vlong *val)
}
static Reloc *
-addpltreloc(Sym *plt, Sym *got, Sym *sym, int typ)
+addpltreloc(Link *ctxt, LSym *plt, LSym *got, LSym *sym, int typ)
{
Reloc *r;
@@ -397,25 +380,25 @@ addpltreloc(Sym *plt, Sym *got, Sym *sym, int typ)
plt->reachable = 1;
plt->size += 4;
- symgrow(plt, plt->size);
+ symgrow(ctxt, plt, plt->size);
return r;
}
static void
-addpltsym(Sym *s)
+addpltsym(Link *ctxt, LSym *s)
{
- Sym *plt, *got, *rel;
+ LSym *plt, *got, *rel;
if(s->plt >= 0)
return;
- adddynsym(s);
+ adddynsym(ctxt, s);
if(iself) {
- plt = lookup(".plt", 0);
- got = lookup(".got.plt", 0);
- rel = lookup(".rel.plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
+ got = linklookup(ctxt, ".got.plt", 0);
+ rel = linklookup(ctxt, ".rel.plt", 0);
if(plt->size == 0)
elfsetupplt();
@@ -424,34 +407,34 @@ addpltsym(Sym *s)
// In theory, all GOT should point to the first PLT entry,
// Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
// dynamic linker won't, so we'd better do it ourselves.
- addaddrplus(got, plt, 0);
+ addaddrplus(ctxt, got, plt, 0);
// .plt entry, this depends on the .got entry
s->plt = plt->size;
- addpltreloc(plt, got, s, D_PLT0); // add lr, pc, #0xXX00000
- addpltreloc(plt, got, s, D_PLT1); // add lr, lr, #0xYY000
- addpltreloc(plt, got, s, D_PLT2); // ldr pc, [lr, #0xZZZ]!
+ addpltreloc(ctxt, plt, got, s, R_PLT0); // add lr, pc, #0xXX00000
+ addpltreloc(ctxt, plt, got, s, R_PLT1); // add lr, lr, #0xYY000
+ addpltreloc(ctxt, plt, got, s, R_PLT2); // ldr pc, [lr, #0xZZZ]!
// rel
- addaddrplus(rel, got, s->got);
- adduint32(rel, ELF32_R_INFO(s->dynid, R_ARM_JUMP_SLOT));
+ addaddrplus(ctxt, rel, got, s->got);
+ adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_ARM_JUMP_SLOT));
} else {
diag("addpltsym: unsupported binary format");
}
}
static void
-addgotsyminternal(Sym *s)
+addgotsyminternal(Link *ctxt, LSym *s)
{
- Sym *got;
+ LSym *got;
if(s->got >= 0)
return;
- got = lookup(".got", 0);
+ got = linklookup(ctxt, ".got", 0);
s->got = got->size;
- addaddrplus(got, s, 0);
+ addaddrplus(ctxt, got, s, 0);
if(iself) {
;
@@ -461,31 +444,31 @@ addgotsyminternal(Sym *s)
}
static void
-addgotsym(Sym *s)
+addgotsym(Link *ctxt, LSym *s)
{
- Sym *got, *rel;
+ LSym *got, *rel;
if(s->got >= 0)
return;
- adddynsym(s);
- got = lookup(".got", 0);
+ adddynsym(ctxt, s);
+ got = linklookup(ctxt, ".got", 0);
s->got = got->size;
- adduint32(got, 0);
+ adduint32(ctxt, got, 0);
if(iself) {
- rel = lookup(".rel", 0);
- addaddrplus(rel, got, s->got);
- adduint32(rel, ELF32_R_INFO(s->dynid, R_ARM_GLOB_DAT));
+ rel = linklookup(ctxt, ".rel", 0);
+ addaddrplus(ctxt, rel, got, s->got);
+ adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_ARM_GLOB_DAT));
} else {
diag("addgotsym: unsupported binary format");
}
}
void
-adddynsym(Sym *s)
+adddynsym(Link *ctxt, LSym *s)
{
- Sym *d;
+ LSym *d;
int t;
char *name;
@@ -495,20 +478,20 @@ adddynsym(Sym *s)
if(iself) {
s->dynid = nelfsym++;
- d = lookup(".dynsym", 0);
+ d = linklookup(ctxt, ".dynsym", 0);
/* name */
name = s->extname;
- adduint32(d, addstring(lookup(".dynstr", 0), name));
+ adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
/* value */
if(s->type == SDYNIMPORT)
- adduint32(d, 0);
+ adduint32(ctxt, d, 0);
else
- addaddr(d, s);
+ addaddr(ctxt, d, s);
/* size */
- adduint32(d, 0);
+ adduint32(ctxt, d, 0);
/* type */
t = STB_GLOBAL << 4;
@@ -516,12 +499,12 @@ adddynsym(Sym *s)
t |= STT_FUNC;
else
t |= STT_OBJECT;
- adduint8(d, t);
- adduint8(d, 0);
+ adduint8(ctxt, d, t);
+ adduint8(ctxt, d, 0);
/* shndx */
if(s->type == SDYNIMPORT)
- adduint16(d, SHN_UNDEF);
+ adduint16(ctxt, d, SHN_UNDEF);
else {
switch(s->type) {
default:
@@ -538,7 +521,7 @@ adddynsym(Sym *s)
t = 14;
break;
}
- adduint16(d, t);
+ adduint16(ctxt, d, t);
}
} else {
diag("adddynsym: unsupported binary format");
@@ -548,39 +531,27 @@ adddynsym(Sym *s)
void
adddynlib(char *lib)
{
- Sym *s;
+ LSym *s;
if(!needlib(lib))
return;
if(iself) {
- s = lookup(".dynstr", 0);
+ s = linklookup(ctxt, ".dynstr", 0);
if(s->size == 0)
addstring(s, "");
- elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib));
+ elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
} else {
diag("adddynlib: unsupported binary format");
}
}
-vlong
-datoff(vlong addr)
-{
- if(addr >= segdata.vaddr)
- return addr - segdata.vaddr + segdata.fileoff;
- if(addr >= segtext.vaddr)
- return addr - segtext.vaddr + segtext.fileoff;
- diag("datoff %#x", addr);
- return 0;
-}
-
void
asmb(void)
{
- int32 t;
uint32 symo;
Section *sect;
- Sym *sym;
+ LSym *sym;
int i;
if(debug['v'])
@@ -627,13 +598,7 @@ asmb(void)
default:
if(iself)
goto ElfSym;
- case Hnoheader:
- case Hrisc:
- case Hixp1200:
- case Hipaq:
- debug['s'] = 1;
- break;
- case Hplan9x32:
+ case Hplan9:
symo = HEADR+segtext.len+segdata.filelen;
break;
ElfSym:
@@ -659,11 +624,11 @@ asmb(void)
elfemitreloc();
}
break;
- case Hplan9x32:
+ case Hplan9:
asmplan9sym();
cflush();
- sym = lookup("pclntab", 0);
+ sym = linklookup(ctxt, "pclntab", 0);
if(sym != nil) {
lcsize = sym->np;
for(i=0; i < lcsize; i++)
@@ -675,46 +640,14 @@ asmb(void)
}
}
- cursym = nil;
+ ctxt->cursym = nil;
if(debug['v'])
Bprint(&bso, "%5.2f header\n", cputime());
Bflush(&bso);
cseek(0L);
switch(HEADTYPE) {
default:
- case Hnoheader: /* no header */
- break;
- case Hrisc: /* aif for risc os */
- lputl(0xe1a00000); /* NOP - decompress code */
- lputl(0xe1a00000); /* NOP - relocation code */
- lputl(0xeb000000 + 12); /* BL - zero init code */
- lputl(0xeb000000 +
- (entryvalue()
- - INITTEXT
- + HEADR
- - 12
- - 8) / 4); /* BL - entry code */
-
- lputl(0xef000011); /* SWI - exit code */
- lputl(segtext.filelen+HEADR); /* text size */
- lputl(segdata.filelen); /* data size */
- lputl(0); /* sym size */
-
- lputl(segdata.len - segdata.filelen); /* bss size */
- lputl(0); /* sym type */
- lputl(INITTEXT-HEADR); /* text addr */
- lputl(0); /* workspace - ignored */
-
- lputl(32); /* addr mode / data addr flag */
- lputl(0); /* data addr */
- for(t=0; t<2; t++)
- lputl(0); /* reserved */
-
- for(t=0; t<15; t++)
- lputl(0xe1a00000); /* NOP - zero init code */
- lputl(0xe1a0f00e); /* B (R14) - zero init return */
- break;
- case Hplan9x32: /* plan 9 */
+ case Hplan9: /* plan 9 */
lput(0x647); /* magic */
lput(segtext.filelen); /* sizes */
lput(segdata.filelen);
@@ -724,14 +657,6 @@ asmb(void)
lput(0L);
lput(lcsize);
break;
- case Hixp1200: /* boot for IXP1200 */
- break;
- case Hipaq: /* boot for ipaq */
- lputl(0xe3300000); /* nop */
- lputl(0xe3300000); /* nop */
- lputl(0xe3300000); /* nop */
- lputl(0xe3300000); /* nop */
- break;
case Hlinux:
case Hfreebsd:
case Hnetbsd:
@@ -808,1224 +733,17 @@ nopstat(char *f, Count *c)
(double)(c->outof - c->count)/c->outof);
}
-void
-asmout(Prog *p, Optab *o, int32 *out, Sym *gmsym)
-{
- int32 o1, o2, o3, o4, o5, o6, v;
- int r, rf, rt, rt2;
- Reloc *rel;
-
-PP = p;
- o1 = 0;
- o2 = 0;
- o3 = 0;
- o4 = 0;
- o5 = 0;
- o6 = 0;
- armsize += o->size;
-if(debug['P']) print("%ux: %P type %d\n", (uint32)(p->pc), p, o->type);
- switch(o->type) {
- default:
- diag("unknown asm %d", o->type);
- prasm(p);
- break;
-
- case 0: /* pseudo ops */
-if(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(p->as, p->scond);
- rf = p->from.reg;
- rt = p->to.reg;
- r = p->reg;
- if(p->to.type == D_NONE)
- rt = 0;
- if(p->as == AMOVB || p->as == AMOVH || p->as == AMOVW || p->as == AMVN)
- r = 0;
- else
- if(r == NREG)
- r = rt;
- o1 |= rf | (r<<16) | (rt<<12);
- break;
-
- case 2: /* movbu $I,[R],R */
- aclass(&p->from);
- o1 = oprrr(p->as, p->scond);
- o1 |= immrot(instoffset);
- rt = p->to.reg;
- r = p->reg;
- if(p->to.type == D_NONE)
- rt = 0;
- if(p->as == AMOVW || p->as == AMVN)
- r = 0;
- else if(r == NREG)
- r = rt;
- o1 |= (r<<16) | (rt<<12);
- break;
-
- case 3: /* add R<<[IR],[R],R */
- mov:
- aclass(&p->from);
- o1 = oprrr(p->as, p->scond);
- o1 |= p->from.offset;
- rt = p->to.reg;
- r = p->reg;
- if(p->to.type == D_NONE)
- rt = 0;
- if(p->as == AMOVW || p->as == AMVN)
- r = 0;
- else if(r == NREG)
- r = rt;
- o1 |= (r<<16) | (rt<<12);
- break;
-
- case 4: /* add $I,[R],R */
- aclass(&p->from);
- o1 = oprrr(AADD, p->scond);
- o1 |= immrot(instoffset);
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o1 |= r << 16;
- o1 |= p->to.reg << 12;
- break;
-
- case 5: /* bra s */
- o1 = opbra(p->as, p->scond);
- v = -8;
- if(p->to.sym != S && p->to.sym->type != 0) {
- rel = addrel(cursym);
- rel->off = pc - cursym->value;
- rel->siz = 4;
- rel->sym = p->to.sym;
- rel->add = o1 | ((v >> 2) & 0xffffff);
- rel->type = D_CALL;
- break;
- }
- if(p->cond != P)
- v = (p->cond->pc - pc) - 8;
- o1 |= (v >> 2) & 0xffffff;
- break;
-
- case 6: /* b ,O(R) -> add $O,R,PC */
- aclass(&p->to);
- o1 = oprrr(AADD, p->scond);
- o1 |= immrot(instoffset);
- o1 |= p->to.reg << 16;
- o1 |= REGPC << 12;
- break;
-
- case 7: /* bl (R) -> blx R */
- aclass(&p->to);
- if(instoffset != 0)
- diag("%P: doesn't support BL offset(REG) where offset != 0", p);
- o1 = oprrr(ABL, p->scond);
- o1 |= p->to.reg;
- break;
-
- case 8: /* sll $c,[R],R -> mov (R<<$c),R */
- aclass(&p->from);
- o1 = oprrr(p->as, p->scond);
- r = p->reg;
- if(r == NREG)
- r = p->to.reg;
- o1 |= r;
- o1 |= (instoffset&31) << 7;
- o1 |= p->to.reg << 12;
- break;
-
- case 9: /* sll R,[R],R -> mov (R<<R),R */
- o1 = oprrr(p->as, p->scond);
- r = p->reg;
- if(r == NREG)
- r = p->to.reg;
- o1 |= r;
- o1 |= (p->from.reg << 8) | (1<<4);
- o1 |= p->to.reg << 12;
- break;
-
- case 10: /* swi [$con] */
- o1 = oprrr(p->as, p->scond);
- if(p->to.type != D_NONE) {
- aclass(&p->to);
- o1 |= instoffset & 0xffffff;
- }
- break;
-
- case 11: /* word */
- aclass(&p->to);
- o1 = instoffset;
- if(p->to.sym != S) {
- rel = addrel(cursym);
- rel->off = pc - cursym->value;
- rel->siz = 4;
- rel->sym = p->to.sym;
- rel->add = p->to.offset;
- if(rel->sym == gmsym) {
- rel->type = D_TLS;
- if(flag_shared)
- rel->add += pc - p->pcrel->pc - 8 - rel->siz;
- rel->xadd = rel->add;
- rel->xsym = rel->sym;
- } else if(flag_shared) {
- rel->type = D_PCREL;
- rel->add += pc - p->pcrel->pc - 8;
- } else
- rel->type = D_ADDR;
- o1 = 0;
- }
- break;
-
- case 12: /* movw $lcon, reg */
- o1 = omvl(p, &p->from, p->to.reg);
- if(o->flag & LPCREL) {
- o2 = oprrr(AADD, p->scond) | p->to.reg | REGPC << 16 | p->to.reg << 12;
- }
- break;
-
- case 13: /* op $lcon, [R], R */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- o2 = oprrr(p->as, p->scond);
- o2 |= REGTMP;
- r = p->reg;
- if(p->as == AMOVW || p->as == AMVN)
- r = 0;
- else if(r == NREG)
- r = p->to.reg;
- o2 |= r << 16;
- if(p->to.type != D_NONE)
- o2 |= p->to.reg << 12;
- break;
-
- case 14: /* movb/movbu/movh/movhu R,R */
- o1 = oprrr(ASLL, p->scond);
-
- if(p->as == AMOVBU || p->as == AMOVHU)
- o2 = oprrr(ASRL, p->scond);
- else
- o2 = oprrr(ASRA, p->scond);
-
- r = p->to.reg;
- o1 |= (p->from.reg)|(r<<12);
- o2 |= (r)|(r<<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(p->as, p->scond);
- rf = p->from.reg;
- rt = p->to.reg;
- r = p->reg;
- if(r == NREG)
- r = rt;
- if(rt == r) {
- r = rf;
- rf = rt;
- }
- if(0)
- if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) {
- diag("bad registers in MUL");
- prasm(p);
- }
- o1 |= (rf<<8) | r | (rt<<16);
- break;
-
-
- case 16: /* div r,[r,]r */
- o1 = 0xf << 28;
- o2 = 0;
- break;
-
- case 17:
- o1 = oprrr(p->as, p->scond);
- rf = p->from.reg;
- rt = p->to.reg;
- rt2 = p->to.offset;
- r = p->reg;
- o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12);
- break;
-
- case 20: /* mov/movb/movbu R,O(R) */
- aclass(&p->to);
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o1 = osr(p->as, p->from.reg, instoffset, r, p->scond);
- break;
-
- case 21: /* mov/movbu O(R),R -> lr */
- aclass(&p->from);
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o1 = olr(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(p, &p->to, REGTMP);
- if(!o1)
- break;
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o2 = osrr(p->from.reg, REGTMP,r, p->scond);
- if(p->as != AMOVW)
- o2 |= 1<<22;
- break;
-
- case 31: /* mov/movbu L(R),R -> lr[b] */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o2 = olrr(REGTMP,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(p, &p->from, REGTMP);
- if(!o1)
- break;
-
- o2 = oprrr(AADD, p->scond);
- o2 |= REGTMP;
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o2 |= r << 16;
- if(p->to.type != D_NONE)
- o2 |= p->to.reg << 12;
- break;
-
- case 35: /* mov PSR,R */
- o1 = (2<<23) | (0xf<<16) | (0<<0);
- o1 |= (p->scond & C_SCOND) << 28;
- o1 |= (p->from.reg & 1) << 22;
- o1 |= p->to.reg << 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) << 28;
- o1 |= (p->to.reg & 1) << 22;
- o1 |= p->from.reg << 0;
- break;
-
- case 37: /* mov $con,PSR */
- aclass(&p->from);
- o1 = (2<<23) | (0x29f<<12) | (0<<4);
- if(p->scond & C_FBIT)
- o1 ^= 0x010 << 12;
- o1 |= (p->scond & C_SCOND) << 28;
- o1 |= immrot(instoffset);
- o1 |= (p->to.reg & 1) << 22;
- o1 |= p->from.reg << 0;
- break;
-
- case 38: /* movm $con,oreg -> stm */
- o1 = (0x4 << 25);
- o1 |= p->from.offset & 0xffff;
- o1 |= p->to.reg << 16;
- aclass(&p->to);
- goto movm;
-
- case 39: /* movm oreg,$con -> ldm */
- o1 = (0x4 << 25) | (1 << 20);
- o1 |= p->to.offset & 0xffff;
- o1 |= p->from.reg << 16;
- aclass(&p->from);
- movm:
- if(instoffset != 0)
- diag("offset must be zero in MOVM");
- o1 |= (p->scond & C_SCOND) << 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(&p->from);
- if(instoffset != 0)
- diag("offset must be zero in SWP");
- o1 = (0x2<<23) | (0x9<<4);
- if(p->as != ASWPW)
- o1 |= 1 << 22;
- o1 |= p->from.reg << 16;
- o1 |= p->reg << 0;
- o1 |= p->to.reg << 12;
- o1 |= (p->scond & C_SCOND) << 28;
- break;
-
- case 41: /* rfe -> movm.s.w.u 0(r13),[r15] */
- o1 = 0xe8fd8000;
- break;
-
- case 50: /* floating point store */
- v = regoff(&p->to);
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o1 = ofsr(p->as, p->from.reg, v, r, p->scond, p);
- break;
-
- case 51: /* floating point load */
- v = regoff(&p->from);
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o1 = ofsr(p->as, p->to.reg, v, r, p->scond, p) | (1<<20);
- break;
-
- case 52: /* floating point store, int32 offset UGLY */
- o1 = omvl(p, &p->to, REGTMP);
- if(!o1)
- break;
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
- o3 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);
- break;
-
- case 53: /* floating point load, int32 offset UGLY */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
- o3 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
- break;
-
- case 54: /* floating point arith */
- o1 = oprrr(p->as, p->scond);
- rf = p->from.reg;
- rt = p->to.reg;
- r = p->reg;
- if(r == NREG) {
- r = rt;
- if(p->as == AMOVF || p->as == AMOVD || p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
- r = 0;
- }
- o1 |= rf | (r<<16) | (rt<<12);
- break;
-
- case 56: /* move to FP[CS]R */
- o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
- o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12);
- break;
-
- case 57: /* move from FP[CS]R */
- o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
- o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20);
- break;
- case 58: /* movbu R,R */
- o1 = oprrr(AAND, p->scond);
- o1 |= immrot(0xff);
- rt = p->to.reg;
- r = p->from.reg;
- if(p->to.type == D_NONE)
- rt = 0;
- if(r == NREG)
- r = rt;
- o1 |= (r<<16) | (rt<<12);
- break;
-
- case 59: /* movw/bu R<<I(R),R -> ldr indexed */
- if(p->from.reg == NREG) {
- if(p->as != AMOVW)
- diag("byte MOV from shifter operand");
- goto mov;
- }
- if(p->from.offset&(1<<4))
- diag("bad shift in LDR");
- o1 = olrr(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 == NREG) {
- diag("byte MOV from shifter operand");
- goto mov;
- }
- if(p->from.offset&(~0xf))
- diag("bad shift in LDRSB");
- o1 = olhrr(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 == NREG)
- diag("MOV to shifter operand");
- o1 = osrr(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(AADD, p->scond) | immrot(1) | p->from.reg << 16 | REGTMP << 12;
- o2 = olrr(REGTMP, REGPC, REGTMP, p->scond);
- o2 |= 2<<7;
- o3 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGPC << 12;
- } else {
- o1 = olrr(p->from.reg, REGPC, REGPC, p->scond);
- o1 |= 2<<7;
- }
- break;
-
- case 63: /* bcase */
- if(p->cond != P) {
- rel = addrel(cursym);
- rel->off = pc - cursym->value;
- rel->siz = 4;
- if(p->to.sym != S && p->to.sym->type != 0) {
- rel->sym = p->to.sym;
- rel->add = p->to.offset;
- } else {
- rel->sym = cursym;
- rel->add = p->cond->pc - cursym->value;
- }
- if(o->flag & LPCREL) {
- rel->type = D_PCREL;
- rel->add += pc - p->pcrel->pc - 16 + rel->siz;
- } else
- rel->type = D_ADDR;
- o1 = 0;
- }
- break;
-
- /* reloc ops */
- case 64: /* mov/movb/movbu R,addr */
- o1 = omvl(p, &p->to, REGTMP);
- if(!o1)
- break;
- o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
- if(o->flag & LPCREL) {
- o3 = o2;
- o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
- }
- break;
-
- case 65: /* mov/movbu addr,R */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- o2 = olr(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(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
- }
- break;
-
- case 68: /* floating point store -> ADDR */
- o1 = omvl(p, &p->to, REGTMP);
- if(!o1)
- break;
- o2 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);
- if(o->flag & LPCREL) {
- o3 = o2;
- o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
- }
- break;
-
- case 69: /* floating point load <- ADDR */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- o2 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
- if(o->flag & LPCREL) {
- o3 = o2;
- o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
- }
- break;
-
- /* ArmV4 ops: */
- case 70: /* movh/movhu R,O(R) -> strh */
- aclass(&p->to);
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o1 = oshr(p->from.reg, instoffset, r, p->scond);
- break;
- case 71: /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
- aclass(&p->from);
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o1 = olhr(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(p, &p->to, REGTMP);
- if(!o1)
- break;
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o2 = oshrr(p->from.reg, REGTMP,r, p->scond);
- break;
- case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o2 = olhrr(REGTMP, 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 */
- diag("ABX $I");
- break;
- case 75: /* bx O(R) */
- aclass(&p->to);
- if(instoffset != 0)
- diag("non-zero offset in ABX");
-/*
- o1 = oprrr(AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR
- o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R
-*/
- // p->to.reg may be REGLINK
- o1 = oprrr(AADD, p->scond);
- o1 |= immrot(instoffset);
- o1 |= p->to.reg << 16;
- o1 |= REGTMP << 12;
- o2 = oprrr(AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR
- o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP; // BX Rtmp
- break;
- case 76: /* bx O(R) when returning from fn*/
- diag("ABXRET");
- break;
- case 77: /* ldrex oreg,reg */
- aclass(&p->from);
- if(instoffset != 0)
- diag("offset must be zero in LDREX");
- o1 = (0x19<<20) | (0xf9f);
- o1 |= p->from.reg << 16;
- o1 |= p->to.reg << 12;
- o1 |= (p->scond & C_SCOND) << 28;
- break;
- case 78: /* strex reg,oreg,reg */
- aclass(&p->from);
- if(instoffset != 0)
- diag("offset must be zero in STREX");
- o1 = (0x18<<20) | (0xf90);
- o1 |= p->from.reg << 16;
- o1 |= p->reg << 0;
- o1 |= p->to.reg << 12;
- o1 |= (p->scond & C_SCOND) << 28;
- break;
- case 80: /* fmov zfcon,freg */
- if(p->as == AMOVD) {
- o1 = 0xeeb00b00; // VMOV imm 64
- o2 = oprrr(ASUBD, p->scond);
- } else {
- o1 = 0x0eb00a00; // VMOV imm 32
- o2 = oprrr(ASUBF, p->scond);
- }
- v = 0x70; // 1.0
- r = p->to.reg;
-
- // movf $1.0, r
- o1 |= (p->scond & C_SCOND) << 28;
- o1 |= r << 12;
- o1 |= (v&0xf) << 0;
- o1 |= (v&0xf0) << 12;
-
- // subf r,r,r
- o2 |= r | (r<<16) | (r<<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) << 28;
- o1 |= p->to.reg << 12;
- v = chipfloat(&p->from.ieee);
- o1 |= (v&0xf) << 0;
- o1 |= (v&0xf0) << 12;
- break;
- case 82: /* fcmp freg,freg, */
- o1 = oprrr(p->as, p->scond);
- o1 |= (p->reg<<12) | (p->from.reg<<0);
- o2 = 0x0ef1fa10; // VMRS R15
- o2 |= (p->scond & C_SCOND) << 28;
- break;
- case 83: /* fcmp freg,, */
- o1 = oprrr(p->as, p->scond);
- o1 |= (p->from.reg<<12) | (1<<16);
- o2 = 0x0ef1fa10; // VMRS R15
- o2 |= (p->scond & C_SCOND) << 28;
- break;
- case 84: /* movfw freg,freg - truncate float-to-fix */
- o1 = oprrr(p->as, p->scond);
- o1 |= (p->from.reg<<0);
- o1 |= (p->to.reg<<12);
- break;
- case 85: /* movwf freg,freg - fix-to-float */
- o1 = oprrr(p->as, p->scond);
- o1 |= (p->from.reg<<0);
- o1 |= (p->to.reg<<12);
- break;
- case 86: /* movfw freg,reg - truncate float-to-fix */
- // macro for movfw freg,FTMP; movw FTMP,reg
- o1 = oprrr(p->as, p->scond);
- o1 |= (p->from.reg<<0);
- o1 |= (FREGTMP<<12);
- o2 = oprrr(AMOVFW+AEND, p->scond);
- o2 |= (FREGTMP<<16);
- o2 |= (p->to.reg<<12);
- break;
- case 87: /* movwf reg,freg - fix-to-float */
- // macro for movw reg,FTMP; movwf FTMP,freg
- o1 = oprrr(AMOVWF+AEND, p->scond);
- o1 |= (p->from.reg<<12);
- o1 |= (FREGTMP<<16);
- o2 = oprrr(p->as, p->scond);
- o2 |= (FREGTMP<<0);
- o2 |= (p->to.reg<<12);
- break;
- case 88: /* movw reg,freg */
- o1 = oprrr(AMOVWF+AEND, p->scond);
- o1 |= (p->from.reg<<12);
- o1 |= (p->to.reg<<16);
- break;
- case 89: /* movw freg,reg */
- o1 = oprrr(AMOVFW+AEND, p->scond);
- o1 |= (p->from.reg<<16);
- o1 |= (p->to.reg<<12);
- break;
- case 90: /* tst reg */
- o1 = oprrr(ACMP+AEND, p->scond);
- o1 |= p->from.reg<<16;
- break;
- case 91: /* ldrexd oreg,reg */
- aclass(&p->from);
- if(instoffset != 0)
- diag("offset must be zero in LDREX");
- o1 = (0x1b<<20) | (0xf9f);
- o1 |= p->from.reg << 16;
- o1 |= p->to.reg << 12;
- o1 |= (p->scond & C_SCOND) << 28;
- break;
- case 92: /* strexd reg,oreg,reg */
- aclass(&p->from);
- if(instoffset != 0)
- diag("offset must be zero in STREX");
- o1 = (0x1a<<20) | (0xf90);
- o1 |= p->from.reg << 16;
- o1 |= p->reg << 0;
- o1 |= p->to.reg << 12;
- o1 |= (p->scond & C_SCOND) << 28;
- break;
- case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */
- o1 = omvl(p, &p->from, REGTMP);
- if(!o1)
- break;
- o2 = olhr(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(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
- }
- break;
- case 94: /* movh/movhu R,addr -> strh */
- o1 = omvl(p, &p->to, REGTMP);
- if(!o1)
- break;
- o2 = oshr(p->from.reg, 0, REGTMP, p->scond);
- if(o->flag & LPCREL) {
- o3 = o2;
- o2 = oprrr(AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
- }
- break;
- case 95: /* PLD off(reg) */
- o1 = 0xf5d0f000;
- o1 |= p->from.reg << 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 guranteed to raise undefined instruction
- // exception.
- o1 = 0xf7fabcfd;
- break;
- case 97: /* CLZ Rm, Rd */
- o1 = oprrr(p->as, p->scond);
- o1 |= p->to.reg << 12;
- o1 |= p->from.reg;
- break;
- case 98: /* MULW{T,B} Rs, Rm, Rd */
- o1 = oprrr(p->as, p->scond);
- o1 |= p->to.reg << 16;
- o1 |= p->from.reg << 8;
- o1 |= p->reg;
- break;
- case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */
- o1 = oprrr(p->as, p->scond);
- o1 |= p->to.reg << 12;
- o1 |= p->from.reg << 8;
- o1 |= p->reg;
- o1 |= p->to.offset << 16;
- break;
- }
-
- out[0] = o1;
- out[1] = o2;
- out[2] = o3;
- out[3] = o4;
- out[4] = o5;
- out[5] = o6;
- return;
-
-#ifdef NOTDEF
- v = p->pc;
- switch(o->size) {
- default:
- if(debug['a'])
- Bprint(&bso, " %.8ux:\t\t%P\n", v, p);
- break;
- case 4:
- if(debug['a'])
- Bprint(&bso, " %.8ux: %.8ux\t%P\n", v, o1, p);
- lputl(o1);
- break;
- case 8:
- if(debug['a'])
- Bprint(&bso, " %.8ux: %.8ux %.8ux%P\n", v, o1, o2, p);
- lputl(o1);
- lputl(o2);
- break;
- case 12:
- if(debug['a'])
- Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux%P\n", v, o1, o2, o3, p);
- lputl(o1);
- lputl(o2);
- lputl(o3);
- break;
- case 16:
- if(debug['a'])
- Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux %.8ux%P\n",
- v, o1, o2, o3, o4, p);
- lputl(o1);
- lputl(o2);
- lputl(o3);
- lputl(o4);
- break;
- case 20:
- if(debug['a'])
- Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux %.8ux %.8ux%P\n",
- v, o1, o2, o3, o4, o5, p);
- lputl(o1);
- lputl(o2);
- lputl(o3);
- lputl(o4);
- lputl(o5);
- break;
- case 24:
- if(debug['a'])
- Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux%P\n",
- v, o1, o2, o3, o4, o5, o6, p);
- lputl(o1);
- lputl(o2);
- lputl(o3);
- lputl(o4);
- lputl(o5);
- lputl(o6);
- break;
- }
-#endif
-}
-
-int32
-oprrr(int a, int sc)
-{
- int32 o;
-
- o = (sc & C_SCOND) << 28;
- if(sc & C_SBIT)
- o |= 1 << 20;
- if(sc & (C_PBIT|C_WBIT))
- diag(".P/.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+AEND: // copy WtoF
- return o | (0xe<<24) | (0x0<<20) | (0xb<<8) | (1<<4);
- case AMOVFW+AEND: // copy FtoW
- return o | (0xe<<24) | (0x1<<20) | (0xb<<8) | (1<<4);
- case ACMP+AEND: // cmp imm
- return o | (0x3<<24) | (0x5<<20);
-
- case ACLZ:
- // CLZ doesn't support .S
- 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);
- }
- diag("bad rrr %d", a);
- prasm(curp);
- return 0;
-}
-
-int32
-opbra(int a, int sc)
-{
-
- if(sc & (C_SBIT|C_PBIT|C_WBIT))
- diag(".S/.P/.W on bra instruction");
- sc &= C_SCOND;
- if(a == ABL)
- return (sc<<28)|(0x5<<25)|(0x1<<24);
- if(sc != 0xe)
- 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);
- }
- diag("bad bra %A", a);
- prasm(curp);
- return 0;
-}
-
int32
-olr(int32 v, int b, int r, int sc)
-{
- int32 o;
-
- if(sc & C_SBIT)
- diag(".S on LDR/STR instruction");
- o = (sc & C_SCOND) << 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) diag(".U on neg offset");
- v = -v;
- o ^= 1 << 23;
- }
- if(v >= (1<<12) || v < 0)
- diag("literal span too large: %d (R%d)\n%P", v, b, PP);
- o |= v;
- o |= b << 16;
- o |= r << 12;
- return o;
-}
-
-int32
-olhr(int32 v, int b, int r, int sc)
-{
- int32 o;
-
- if(sc & C_SBIT)
- diag(".S on LDRH/STRH instruction");
- o = (sc & C_SCOND) << 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)
- diag("literal span too large: %d (R%d)\n%P", v, b, PP);
- o |= (v&0xf)|((v>>4)<<8)|(1<<22);
- o |= b << 16;
- o |= r << 12;
- return o;
-}
-
-int32
-osr(int a, int r, int32 v, int b, int sc)
-{
- int32 o;
-
- o = olr(v, b, r, sc) ^ (1<<20);
- if(a != AMOVW)
- o |= 1<<22;
- return o;
-}
-
-int32
-oshr(int r, int32 v, int b, int sc)
-{
- int32 o;
-
- o = olhr(v, b, r, sc) ^ (1<<20);
- return o;
-}
-
-
-int32
-osrr(int r, int i, int b, int sc)
-{
-
- return olr(i, b, r, sc) ^ ((1<<25) | (1<<20));
-}
-
-int32
-oshrr(int r, int i, int b, int sc)
-{
- return olhr(i, b, r, sc) ^ ((1<<22) | (1<<20));
-}
-
-int32
-olrr(int i, int b, int r, int sc)
-{
-
- return olr(i, b, r, sc) ^ (1<<25);
-}
-
-int32
-olhrr(int i, int b, int r, int sc)
-{
- return olhr(i, b, r, sc) ^ (1<<22);
-}
-
-int32
-ofsr(int a, int r, int32 v, int b, int sc, Prog *p)
-{
- int32 o;
-
- if(sc & C_SBIT)
- diag(".S on FLDR/FSTR instruction");
- o = (sc & C_SCOND) << 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)
- diag("odd offset for floating point op: %d\n%P", v, p);
- else
- if(v >= (1<<10) || v < 0)
- diag("literal span too large: %d\n%P", v, p);
- o |= (v>>2) & 0xFF;
- o |= b << 16;
- o |= r << 12;
-
- switch(a) {
- default:
- diag("bad fst %A", a);
- case AMOVD:
- o |= 1 << 8;
- case AMOVF:
- break;
- }
- return o;
-}
-
-int32
-omvl(Prog *p, Adr *a, int dr)
-{
- int32 v, o1;
- if(!p->cond) {
- aclass(a);
- v = immrot(~instoffset);
- if(v == 0) {
- diag("missing literal");
- prasm(p);
- return 0;
- }
- o1 = oprrr(AMVN, p->scond&C_SCOND);
- o1 |= v;
- o1 |= dr << 12;
- } else {
- v = p->cond->pc - p->pc - 8;
- o1 = olr(v, REGPC, dr, p->scond&C_SCOND);
- }
- return o1;
-}
-
-int
-chipzero(Ieee *e)
-{
- // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
- if(goarm < 7 || e->l != 0 || e->h != 0)
- return -1;
- return 0;
-}
-
-int
-chipfloat(Ieee *e)
-{
- int n;
- ulong h;
-
- // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions.
- if(goarm < 7)
- goto no;
-
- if(e->l != 0 || (e->h&0xffff) != 0)
- goto no;
- h = e->h & 0x7fc00000;
- if(h != 0x40000000 && h != 0x3fc00000)
- goto no;
- n = 0;
-
- // sign bit (a)
- if(e->h & 0x80000000)
- n |= 1<<7;
-
- // exp sign bit (b)
- if(h == 0x3fc00000)
- n |= 1<<6;
-
- // rest of exp and mantissa (cd-efgh)
- n |= (e->h >> 16) & 0x3f;
-
-//print("match %.8lux %.8lux %d\n", e->l, e->h, n);
- return n;
-
-no:
- return -1;
+rnd(int32 v, int32 r)
+{
+ int32 c;
+
+ if(r <= 0)
+ return v;
+ v += r - 1;
+ c = v % r;
+ if(c < 0)
+ c += r;
+ v -= c;
+ return v;
}
diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h
index ae4b05ba1..761bc861a 100644
--- a/src/cmd/5l/l.h
+++ b/src/cmd/5l/l.h
@@ -31,6 +31,7 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
+#include <link.h>
#include "5.out.h"
enum
@@ -38,6 +39,7 @@ enum
thechar = '5',
PtrSize = 4,
IntSize = 4,
+ RegSize = 4,
MaxAlign = 8, // max data alignment
FuncAlign = 4 // single-instruction alignment
};
@@ -51,167 +53,13 @@ enum
#define dynptrsize 0
-typedef struct Adr Adr;
-typedef struct Sym Sym;
-typedef struct Autom Auto;
-typedef struct Prog Prog;
-typedef struct Reloc Reloc;
-typedef struct Optab Optab;
-typedef struct Oprang Oprang;
-typedef uchar Opcross[32][2][32];
-typedef struct Count Count;
-
#define P ((Prog*)0)
-#define S ((Sym*)0)
-#define TNAME (cursym?cursym->name:noname)
-
-struct Adr
-{
- union
- {
- struct {
- int32 u0offset;
- int32 u0offset2; // argsize
- } u0off;
- char* u0sval;
- Ieee u0ieee;
- char* u0sbig;
- } u0;
- Sym* sym;
- Sym* gotype;
- char type;
- char reg;
- char name;
- char class;
-};
-
-#define offset u0.u0off.u0offset
-#define offset2 u0.u0off.u0offset2
-#define sval u0.u0sval
-#define scon sval
-#define ieee u0.u0ieee
-#define sbig u0.u0sbig
-
-struct Reloc
-{
- int32 off;
- uchar siz;
- uchar done;
- int16 type;
- int32 add;
- int32 xadd;
- Sym* sym;
- Sym* xsym;
-};
-
-struct Prog
-{
- Adr from;
- Adr to;
- union
- {
- int32 u0regused;
- Prog* u0forwd;
- } u0;
- Prog* cond;
- Prog* link;
- Prog* pcrel;
- int32 pc;
- int32 line;
- int32 spadj;
- uchar mark;
- uchar optab;
- uchar as;
- uchar scond;
- uchar reg;
- uchar align; // unused
-};
-
-#define regused u0.u0regused
-#define forwd u0.u0forwd
-#define datasize reg
-#define textflag reg
-
-#define iscall(p) ((p)->as == ABL)
-
-struct Sym
-{
- char* name;
- char* extname; // name used in external object files
- short type;
- short version;
- uchar dupok;
- uchar reachable;
- uchar cgoexport;
- uchar leaf;
- int32 dynid;
- int32 plt;
- int32 got;
- int32 value;
- int32 sig;
- int32 size;
- int32 align; // if non-zero, required alignment in bytes
- int32 elfsym;
- int32 locals; // size of stack frame locals area
- int32 args; // size of stack frame incoming arguments area
- uchar special;
- uchar fnptr; // used as fn ptr
- uchar stkcheck;
- uchar hide;
- Sym* hash; // in hash table
- Sym* allsym; // in all symbol list
- Sym* next; // in text or data list
- Sym* sub; // in SSUB list
- Sym* outer; // container of sub
- Sym* gotype;
- Sym* reachparent;
- Sym* queue;
- char* file;
- char* dynimplib;
- char* dynimpvers;
- struct Section* sect;
- struct Hist* hist;
-
- // STEXT
- Auto* autom;
- Prog* text;
-
- // SDATA, SBSS
- uchar* p;
- int32 np;
- int32 maxp;
- Reloc* r;
- int32 nr;
- int32 maxr;
-};
+#define S ((LSym*)0)
+#define TNAME (ctxt->cursym?ctxt->cursym->name:noname)
#define SIGNINTERN (1729*325*1729)
-struct Autom
-{
- Sym* asym;
- Auto* link;
- int32 aoffset;
- short type;
- Sym* gotype;
-};
-struct Optab
-{
- char as;
- uchar a1;
- char a2;
- uchar a3;
- uchar type;
- char size;
- char param;
- char flag;
- uchar pcrelsiz;
-};
-struct Oprang
-{
- Optab* start;
- Optab* stop;
-};
+typedef struct Count Count;
struct Count
{
int32 count;
@@ -220,10 +68,17 @@ struct Count
enum
{
- LFROM = 1<<0,
- LTO = 1<<1,
- LPOOL = 1<<2,
- LPCREL = 1<<3,
+/* mark flags */
+ FOLL = 1<<0,
+ LABEL = 1<<1,
+ LEAF = 1<<2,
+
+ STRINGSZ = 200,
+ MINSIZ = 64,
+ NENT = 100,
+ MAXIO = 8192,
+ MAXHIST = 40, /* limit of path elements for history symbols */
+ MINLC = 4,
C_NONE = 0,
C_REG,
@@ -260,7 +115,7 @@ enum
C_HFOREG,
C_SOREG,
C_ROREG,
- C_SROREG, /* both S and R */
+ C_SROREG, /* both nil and R */
C_LOREG,
C_PC,
@@ -270,179 +125,45 @@ enum
C_ADDR, /* reference to relocatable address */
C_GOK,
-
-/* mark flags */
- FOLL = 1<<0,
- LABEL = 1<<1,
- LEAF = 1<<2,
-
- STRINGSZ = 200,
- MINSIZ = 64,
- NENT = 100,
- MAXIO = 8192,
- MAXHIST = 40, /* limit of path elements for history symbols */
- MINLC = 4,
};
#ifndef COFFCVT
-EXTERN int32 HEADR; /* length of header */
-EXTERN int HEADTYPE; /* type of header */
-EXTERN int32 INITDAT; /* data location */
-EXTERN int32 INITRND; /* data round above text location */
-EXTERN int32 INITTEXT; /* text location */
-EXTERN char* INITENTRY; /* entry point */
EXTERN int32 autosize;
-EXTERN Auto* curauto;
-EXTERN Auto* curhist;
-EXTERN Prog* curp;
-EXTERN Sym* cursym;
-EXTERN Sym* datap;
+EXTERN LSym* datap;
EXTERN int debug[128];
-EXTERN Sym* etextp;
EXTERN char* noname;
EXTERN Prog* lastp;
EXTERN int32 lcsize;
EXTERN char literal[32];
EXTERN int nerrors;
EXTERN int32 instoffset;
-EXTERN Opcross opcross[8];
-EXTERN Oprang oprange[ALAST];
-EXTERN char* outfile;
-EXTERN int32 pc;
-EXTERN uchar repop[ALAST];
-EXTERN char* interpreter;
EXTERN char* rpath;
EXTERN uint32 stroffset;
EXTERN int32 symsize;
-EXTERN Sym* textp;
-EXTERN char xcmp[C_GOK+1][C_GOK+1];
-EXTERN Prog zprg;
-EXTERN int dtype;
-EXTERN int tlsoffset;
EXTERN int armsize;
-EXTERN int goarm;
-EXTERN Sym* adrgotype; // type symbol on last Adr read
-EXTERN Sym* fromgotype; // type symbol on last p->from read
-
-extern char* anames[];
-extern Optab optab[];
-
-void addpool(Prog*, Adr*);
-EXTERN Prog* blitrl;
-EXTERN Prog* elitrl;
-EXTERN int goarm;
+#pragma varargck type "I" uint32*
-void initdiv(void);
-EXTERN Prog* prog_div;
-EXTERN Prog* prog_divu;
-EXTERN Prog* prog_mod;
-EXTERN Prog* prog_modu;
-
-#pragma varargck type "A" int
-#pragma varargck type "C" int
-#pragma varargck type "D" Adr*
-#pragma varargck type "I" uchar*
-#pragma varargck type "N" Adr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "S" char*
-#pragma varargck type "Z" char*
-#pragma varargck type "i" char*
-
-int Aconv(Fmt*);
-int Cconv(Fmt*);
-int Dconv(Fmt*);
-int Iconv(Fmt*);
-int Nconv(Fmt*);
-int Oconv(Fmt*);
-int Pconv(Fmt*);
-int Sconv(Fmt*);
-int aclass(Adr*);
-void addhist(int32, int);
-Prog* appendp(Prog*);
+int Iconv(Fmt *fp);
+void adddynlib(char *lib);
+void adddynrel(LSym *s, Reloc *r);
+void adddynrela(LSym *rel, LSym *s, Reloc *r);
+void adddynsym(Link *ctxt, LSym *s);
+int archreloc(Reloc *r, LSym *s, vlong *val);
void asmb(void);
-void asmout(Prog*, Optab*, int32*, Sym*);
-int32 atolwhex(char*);
-Prog* brloop(Prog*);
-void buildop(void);
-void buildrep(int, int);
-void cflush(void);
-int chipzero(Ieee*);
-int chipfloat(Ieee*);
-int cmp(int, int);
-int compound(Prog*);
-double cputime(void);
-void diag(char*, ...);
-void divsig(void);
-void dodata(void);
-void doprof1(void);
-void doprof2(void);
-int32 entryvalue(void);
-void exchange(Prog*);
-void follow(void);
-void hputl(int);
-int isnop(Prog*);
+void cput(int32 c);
+int elfreloc1(Reloc *r, vlong sectoff);
+void elfsetupplt(void);
+void hput(int32 l);
void listinit(void);
-Sym* lookup(char*, int);
-void cput(int);
-void hput(int32);
-void lput(int32);
-void lputb(int32);
-void lputl(int32);
-void* mysbrk(uint32);
-void names(void);
-void nocache(Prog*);
-int ocmp(const void*, const void*);
-int32 opirr(int);
-Optab* oplook(Prog*);
-int32 oprrr(int, int);
-int32 olr(int32, int, int, int);
-int32 olhr(int32, int, int, int);
-int32 olrr(int, int, int, int);
-int32 olhrr(int, int, int, int);
-int32 osr(int, int, int32, int, int);
-int32 oshr(int, int32, int, int);
-int32 ofsr(int, int, int32, int, int, Prog*);
-int32 osrr(int, int, int, int);
-int32 oshrr(int, int, int, int);
-int32 omvl(Prog*, Adr*, int);
-void patch(void);
-void prasm(Prog*);
-void prepend(Prog*, Prog*);
-Prog* prg(void);
-int pseudo(Prog*);
-int32 regoff(Adr*);
-int relinv(int);
-int32 rnd(int32, int32);
-void softfloat(void);
-void span(void);
-void strnput(char*, int);
-int32 symaddr(Sym*);
-void undef(void);
-void vputb(uint64);
-void vputl(uint64);
-void wputb(uint16);
-void wput(int32);
-void wputl(ushort w);
-void xdefine(char*, int, int32);
+void lput(int32 l);
+int machoreloc1(Reloc *r, vlong sectoff);
+void main(int argc, char *argv[]);
void noops(void);
-int32 immrot(uint32);
-int32 immaddr(int32);
-int32 opbra(int, int);
-int brextra(Prog*);
-int isbranch(Prog*);
-void doelf(void);
-void dozerostk(void); // used by -Z
-
-vlong addaddr(Sym *s, Sym *t);
-vlong addsize(Sym *s, Sym *t);
-vlong addstring(Sym *s, char *str);
-vlong adduint16(Sym *s, uint16 v);
-vlong adduint32(Sym *s, uint32 v);
-vlong adduint64(Sym *s, uint64 v);
-vlong adduint8(Sym *s, uint8 v);
-vlong adduintxx(Sym *s, uint64 v, int wid);
+void nopstat(char *f, Count *c);
+int32 rnd(int32 v, int32 r);
+void wput(int32 l);
/* Native is little-endian */
#define LPUT(a) lputl(a)
diff --git a/src/cmd/5l/list.c b/src/cmd/5l/list.c
index 7502a3b81..875fc3e6b 100644
--- a/src/cmd/5l/list.c
+++ b/src/cmd/5l/list.c
@@ -36,355 +36,10 @@
void
listinit(void)
{
-
- fmtinstall('A', Aconv);
- fmtinstall('C', Cconv);
- fmtinstall('D', Dconv);
- fmtinstall('P', Pconv);
- fmtinstall('S', Sconv);
- fmtinstall('N', Nconv);
- fmtinstall('O', Oconv); // C_type constants
+ listinit5();
fmtinstall('I', Iconv);
}
-void
-prasm(Prog *p)
-{
- print("%P\n", p);
-}
-
-int
-Pconv(Fmt *fp)
-{
- Prog *p;
- int a;
-
- p = va_arg(fp->args, Prog*);
- curp = p;
- a = p->as;
- switch(a) {
- default:
- fmtprint(fp, "(%d)", p->line);
- if(p->reg == NREG && p->as != AGLOBL)
- fmtprint(fp, " %A%C %D,%D",
- a, p->scond, &p->from, &p->to);
- else
- if(p->from.type != D_FREG)
- fmtprint(fp, " %A%C %D,R%d,%D",
- a, p->scond, &p->from, p->reg, &p->to);
- else
- fmtprint(fp, " %A%C %D,F%d,%D",
- a, p->scond, &p->from, p->reg, &p->to);
- break;
-
- case ASWPW:
- case ASWPBU:
- fmtprint(fp, "(%d) %A%C R%d,%D,%D",
- p->line, a, p->scond, p->reg, &p->from, &p->to);
- break;
-
- case ADATA:
- case AINIT_:
- case ADYNT_:
- fmtprint(fp, "(%d) %A%C %D/%d,%D",
- p->line, a, p->scond, &p->from, p->reg, &p->to);
- break;
-
- case AWORD:
- fmtprint(fp, "(%d) WORD %D", p->line, &p->to);
- break;
-
- case ADWORD:
- fmtprint(fp, "(%d) DWORD %D %D", p->line, &p->from, &p->to);
- break;
- }
-
- if(p->spadj)
- fmtprint(fp, " (spadj%+d)", p->spadj);
-
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- char *s;
- int a;
-
- a = va_arg(fp->args, int);
- s = "???";
- if(a >= AXXX && a < ALAST)
- s = anames[a];
- return fmtstrcpy(fp, s);
-}
-
-char* strcond[16] =
-{
- ".EQ",
- ".NE",
- ".HS",
- ".LO",
- ".MI",
- ".PL",
- ".VS",
- ".VC",
- ".HI",
- ".LS",
- ".GE",
- ".LT",
- ".GT",
- ".LE",
- "",
- ".NV"
-};
-
-int
-Cconv(Fmt *fp)
-{
- char s[20];
- int c;
-
- c = va_arg(fp->args, int);
- strcpy(s, strcond[c & C_SCOND]);
- if(c & C_SBIT)
- strcat(s, ".S");
- if(c & C_PBIT)
- strcat(s, ".P");
- if(c & C_WBIT)
- strcat(s, ".W");
- if(c & C_UBIT) /* ambiguous with FBIT */
- strcat(s, ".U");
- return fmtstrcpy(fp, s);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ];
- const char *op;
- Adr *a;
- int32 v;
-
- a = va_arg(fp->args, Adr*);
- switch(a->type) {
-
- default:
- snprint(str, sizeof str, "GOK-type(%d)", a->type);
- break;
-
- case D_NONE:
- str[0] = 0;
- if(a->name != D_NONE || a->reg != NREG || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg);
- break;
-
- case D_CONST:
- if(a->reg == NREG)
- snprint(str, sizeof str, "$%N", a);
- else
- snprint(str, sizeof str, "$%N(R%d)", a, a->reg);
- break;
-
- case D_CONST2:
- snprint(str, sizeof str, "$%d-%d", a->offset, a->offset2);
- break;
-
- case D_SHIFT:
- v = a->offset;
- op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
- if(v & (1<<4))
- snprint(str, sizeof str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
- else
- snprint(str, sizeof str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
- if(a->reg != NREG)
- seprint(str+strlen(str), str+sizeof str, "(R%d)", a->reg);
- break;
-
- case D_OCONST:
- snprint(str, sizeof str, "$*$%N", a);
- if(a->reg != NREG)
- snprint(str, sizeof str, "%N(R%d)(CONST)", a, a->reg);
- break;
-
- case D_OREG:
- if(a->reg != NREG)
- snprint(str, sizeof str, "%N(R%d)", a, a->reg);
- else
- snprint(str, sizeof str, "%N", a);
- break;
-
- case D_REG:
- snprint(str, sizeof str, "R%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_REGREG:
- snprint(str, sizeof str, "(R%d,R%d)", a->reg, (int)a->offset);
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_REGREG2:
- snprint(str, sizeof str, "R%d,R%d", a->reg, (int)a->offset);
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_FREG:
- snprint(str, sizeof str, "F%d", a->reg);
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg);
- break;
-
- case D_PSR:
- switch(a->reg) {
- case 0:
- snprint(str, sizeof str, "CPSR");
- break;
- case 1:
- snprint(str, sizeof str, "SPSR");
- break;
- default:
- snprint(str, sizeof str, "PSR%d", a->reg);
- break;
- }
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(PSR%d)(REG)", a, a->reg);
- break;
-
- case D_FPCR:
- switch(a->reg){
- case 0:
- snprint(str, sizeof str, "FPSR");
- break;
- case 1:
- snprint(str, sizeof str, "FPCR");
- break;
- default:
- snprint(str, sizeof str, "FCR%d", a->reg);
- break;
- }
- if(a->name != D_NONE || a->sym != S)
- snprint(str, sizeof str, "%N(FCR%d)(REG)", a, a->reg);
-
- break;
-
- case D_BRANCH: /* botch */
- if(curp->cond != P) {
- v = curp->cond->pc;
- if(a->sym != S)
- snprint(str, sizeof str, "%s+%.5ux(BRANCH)", a->sym->name, v);
- else
- snprint(str, sizeof str, "%.5ux(BRANCH)", v);
- } else
- if(a->sym != S)
- snprint(str, sizeof str, "%s+%d(APC)", a->sym->name, a->offset);
- else
- snprint(str, sizeof str, "%d(APC)", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof str, "$%e", ieeedtod(&a->ieee));
- break;
-
- case D_SCONST:
- snprint(str, sizeof str, "$\"%S\"", a->sval);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Nconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Adr *a;
- Sym *s;
-
- a = va_arg(fp->args, Adr*);
- s = a->sym;
- switch(a->name) {
- default:
- sprint(str, "GOK-name(%d)", a->name);
- break;
-
- case D_NONE:
- sprint(str, "%d", a->offset);
- break;
-
- case D_EXTERN:
- if(s == S)
- sprint(str, "%d(SB)", a->offset);
- else
- sprint(str, "%s+%d(SB)", s->name, a->offset);
- break;
-
- case D_STATIC:
- if(s == S)
- sprint(str, "<>+%d(SB)", a->offset);
- else
- sprint(str, "%s<>+%d(SB)", s->name, a->offset);
- break;
-
- case D_AUTO:
- if(s == S)
- sprint(str, "%d(SP)", a->offset);
- else
- sprint(str, "%s-%d(SP)", s->name, -a->offset);
- break;
-
- case D_PARAM:
- if(s == S)
- sprint(str, "%d(FP)", a->offset);
- else
- sprint(str, "%s+%d(FP)", s->name, a->offset);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(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);
-}
-
int
Iconv(Fmt *fp)
{
@@ -413,83 +68,3 @@ Iconv(Fmt *fp)
free(s);
return 0;
}
-
-static char*
-cnames[] =
-{
- [C_ADDR] = "C_ADDR",
- [C_FAUTO] = "C_FAUTO",
- [C_ZFCON] = "C_SFCON",
- [C_SFCON] = "C_SFCON",
- [C_LFCON] = "C_LFCON",
- [C_FCR] = "C_FCR",
- [C_FOREG] = "C_FOREG",
- [C_FREG] = "C_FREG",
- [C_GOK] = "C_GOK",
- [C_HAUTO] = "C_HAUTO",
- [C_HFAUTO] = "C_HFAUTO",
- [C_HFOREG] = "C_HFOREG",
- [C_HOREG] = "C_HOREG",
- [C_HREG] = "C_HREG",
- [C_LACON] = "C_LACON",
- [C_LAUTO] = "C_LAUTO",
- [C_LBRA] = "C_LBRA",
- [C_LCON] = "C_LCON",
- [C_LCONADDR] = "C_LCONADDR",
- [C_LOREG] = "C_LOREG",
- [C_NCON] = "C_NCON",
- [C_NONE] = "C_NONE",
- [C_PC] = "C_PC",
- [C_PSR] = "C_PSR",
- [C_RACON] = "C_RACON",
- [C_RCON] = "C_RCON",
- [C_REG] = "C_REG",
- [C_REGREG] = "C_REGREG",
- [C_REGREG2] = "C_REGREG2",
- [C_ROREG] = "C_ROREG",
- [C_SAUTO] = "C_SAUTO",
- [C_SBRA] = "C_SBRA",
- [C_SCON] = "C_SCON",
- [C_SHIFT] = "C_SHIFT",
- [C_SOREG] = "C_SOREG",
- [C_SP] = "C_SP",
- [C_SROREG] = "C_SROREG"
-};
-
-int
-Oconv(Fmt *fp)
-{
- char buf[500];
- int o;
-
- o = va_arg(fp->args, int);
- if(o < 0 || o >= nelem(cnames) || cnames[o] == nil) {
- snprint(buf, sizeof(buf), "C_%d", o);
- return fmtstrcpy(fp, buf);
- }
- return fmtstrcpy(fp, cnames[o]);
-}
-
-void
-diag(char *fmt, ...)
-{
- char buf[1024], *tn, *sep;
- va_list arg;
-
- tn = "";
- sep = "";
- if(cursym != S) {
- tn = cursym->name;
- sep = ": ";
- }
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- print("%s%s%s\n", tn, sep, buf);
-
- nerrors++;
- if(nerrors > 20) {
- print("too many errors\n");
- errorexit();
- }
-}
diff --git a/src/cmd/5l/noop.c b/src/cmd/5l/noop.c
index 305ed684e..d42c86289 100644
--- a/src/cmd/5l/noop.c
+++ b/src/cmd/5l/noop.c
@@ -32,677 +32,12 @@
#include "l.h"
#include "../ld/lib.h"
-#include "../../pkg/runtime/stack.h"
-
-static Sym* sym_div;
-static Sym* sym_divu;
-static Sym* sym_mod;
-static Sym* sym_modu;
-static Sym* symmorestack;
-static Prog* pmorestack;
-
-static Prog* stacksplit(Prog*, int32);
-
-static void
-linkcase(Prog *casep)
-{
- Prog *p;
-
- for(p = casep; p != P; p = p->link){
- if(p->as == ABCASE) {
- for(; p != P && p->as == ABCASE; p = p->link)
- p->pcrel = casep;
- break;
- }
- }
-}
void
noops(void)
{
- Prog *p, *q, *q1, *q2;
- int o;
- Sym *tlsfallback, *gmsym;
-
- /*
- * find leaf subroutines
- * strip NOPs
- * expand RET
- * expand BECOME pseudo
- * fixup TLS
- */
-
- if(debug['v'])
- Bprint(&bso, "%5.2f noops\n", cputime());
- Bflush(&bso);
-
- symmorestack = lookup("runtime.morestack", 0);
- if(symmorestack->type != STEXT) {
- diag("runtime·morestack not defined");
- errorexit();
- }
- pmorestack = symmorestack->text;
- pmorestack->reg |= NOSPLIT;
-
- tlsfallback = lookup("runtime.read_tls_fallback", 0);
- gmsym = S;
- if(linkmode == LinkExternal)
- gmsym = lookup("runtime.tlsgm", 0);
- q = P;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- switch(p->as) {
- case ACASE:
- if(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(prog_div == P)
- initdiv();
- cursym->text->mark &= ~LEAF;
- continue;
-
- case ANOP:
- q1 = p->link;
- q->link = q1; /* q is non-nop */
- if(q1 != P)
- q1->mark |= p->mark;
- continue;
-
- case ABL:
- case ABX:
- 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->cond;
- if(q1 != P) {
- while(q1->as == ANOP) {
- q1 = q1->link;
- p->cond = q1;
- }
- }
- break;
- case AWORD:
- // Rewrite TLS register fetch: MRC 15, 0, <reg>, C13, C0, 3
- if((p->to.offset & 0xffff0fff) == 0xee1d0f70) {
- if(HEADTYPE == Hopenbsd) {
- p->as = ARET;
- } else if(goarm < 7) {
- if(tlsfallback->type != STEXT) {
- diag("runtime·read_tls_fallback not defined");
- errorexit();
- }
- // BL runtime.read_tls_fallback(SB)
- p->as = ABL;
- p->to.type = D_BRANCH;
- p->to.sym = tlsfallback;
- p->cond = tlsfallback->text;
- p->to.offset = 0;
- cursym->text->mark &= ~LEAF;
- }
- if(linkmode == LinkExternal) {
- // runtime.tlsgm is relocated with R_ARM_TLS_LE32
- // and $runtime.tlsgm will contain the TLS offset.
- //
- // MOV $runtime.tlsgm+tlsoffset(SB), REGTMP
- // ADD REGTMP, <reg>
- //
- // In shared mode, runtime.tlsgm is relocated with
- // R_ARM_TLS_IE32 and runtime.tlsgm(SB) will point
- // to the GOT entry containing the TLS offset.
- //
- // MOV runtime.tlsgm(SB), REGTMP
- // ADD REGTMP, <reg>
- // SUB -tlsoffset, <reg>
- //
- // The SUB compensates for tlsoffset
- // used in runtime.save_gm and runtime.load_gm.
- q = p;
- p = appendp(p);
- p->as = AMOVW;
- p->scond = 14;
- p->reg = NREG;
- if(flag_shared) {
- p->from.type = D_OREG;
- p->from.offset = 0;
- } else {
- p->from.type = D_CONST;
- p->from.offset = tlsoffset;
- }
- p->from.sym = gmsym;
- p->from.name = D_EXTERN;
- p->to.type = D_REG;
- p->to.reg = REGTMP;
- p->to.offset = 0;
-
- p = appendp(p);
- p->as = AADD;
- p->scond = 14;
- p->reg = NREG;
- p->from.type = D_REG;
- p->from.reg = REGTMP;
- p->to.type = D_REG;
- p->to.reg = (q->to.offset & 0xf000) >> 12;
- p->to.offset = 0;
-
- if(flag_shared) {
- p = appendp(p);
- p->as = ASUB;
- p->scond = 14;
- p->reg = NREG;
- p->from.type = D_CONST;
- p->from.offset = -tlsoffset;
- p->to.type = D_REG;
- p->to.reg = (q->to.offset & 0xf000) >> 12;
- p->to.offset = 0;
- }
- }
- }
- }
- q = p;
- }
- }
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; 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(debug['v'])
- Bprint(&bso, "save suppressed in: %s\n",
- cursym->name);
- Bflush(&bso);
- cursym->text->mark |= LEAF;
- }
- if(cursym->text->mark & LEAF) {
- cursym->leaf = 1;
- if(!autosize)
- break;
- }
-
- if(!(p->reg & NOSPLIT))
- p = stacksplit(p, autosize); // emit split check
-
- // MOVW.W R14,$-autosize(SP)
- p = appendp(p);
- p->as = AMOVW;
- p->scond |= C_WBIT;
- p->from.type = D_REG;
- p->from.reg = REGLINK;
- p->to.type = D_OREG;
- p->to.offset = -autosize;
- p->to.reg = REGSP;
- p->spadj = autosize;
-
- if(cursym->text->reg & WRAPPER) {
- // g->panicwrap += autosize;
- // MOVW panicwrap_offset(g), R3
- // ADD $autosize, R3
- // MOVW R3 panicwrap_offset(g)
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_OREG;
- p->from.reg = REGG;
- p->from.offset = 2*PtrSize;
- p->to.type = D_REG;
- p->to.reg = 3;
-
- p = appendp(p);
- p->as = AADD;
- p->from.type = D_CONST;
- p->from.offset = autosize;
- p->to.type = D_REG;
- p->to.reg = 3;
-
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_REG;
- p->from.reg = 3;
- p->to.type = D_OREG;
- p->to.reg = REGG;
- p->to.offset = 2*PtrSize;
- }
- break;
-
- case ARET:
- nocache(p);
- if(cursym->text->mark & LEAF) {
- if(!autosize) {
- p->as = AB;
- p->from = zprg.from;
- if(p->to.sym) { // retjmp
- p->to.type = D_BRANCH;
- p->cond = p->to.sym->text;
- } else {
- p->to.type = D_OREG;
- p->to.offset = 0;
- p->to.reg = REGLINK;
- }
- break;
- }
- }
-
- if(cursym->text->reg & WRAPPER) {
- int cond;
-
- // Preserve original RET's cond, to allow RET.EQ
- // in the implementation of reflect.call.
- cond = p->scond;
- p->scond = C_SCOND_NONE;
-
- // g->panicwrap -= autosize;
- // MOVW panicwrap_offset(g), R3
- // SUB $autosize, R3
- // MOVW R3 panicwrap_offset(g)
- p->as = AMOVW;
- p->from.type = D_OREG;
- p->from.reg = REGG;
- p->from.offset = 2*PtrSize;
- p->to.type = D_REG;
- p->to.reg = 3;
- p = appendp(p);
-
- p->as = ASUB;
- p->from.type = D_CONST;
- p->from.offset = autosize;
- p->to.type = D_REG;
- p->to.reg = 3;
- p = appendp(p);
-
- p->as = AMOVW;
- p->from.type = D_REG;
- p->from.reg = 3;
- p->to.type = D_OREG;
- p->to.reg = REGG;
- p->to.offset = 2*PtrSize;
- p = appendp(p);
-
- p->scond = cond;
- }
-
- p->as = AMOVW;
- p->scond |= C_PBIT;
- p->from.type = D_OREG;
- p->from.offset = autosize;
- p->from.reg = REGSP;
- p->to.type = D_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(p);
- q2->as = AB;
- q2->to.type = D_BRANCH;
- q2->to.sym = p->to.sym;
- q2->cond = p->to.sym->text;
- p->to.sym = nil;
- p = q2;
- }
- break;
-
- case AADD:
- if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
- p->spadj = -p->from.offset;
- break;
-
- case ASUB:
- if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
- p->spadj = p->from.offset;
- break;
-
- case ADIV:
- case ADIVU:
- case AMOD:
- case AMODU:
- if(debug['M'])
- break;
- if(p->from.type != D_REG)
- break;
- if(p->to.type != D_REG)
- break;
- q1 = p;
-
- /* MOV a,4(SP) */
- p = appendp(p);
- p->as = AMOVW;
- p->line = q1->line;
- p->from.type = D_REG;
- p->from.reg = q1->from.reg;
- p->to.type = D_OREG;
- p->to.reg = REGSP;
- p->to.offset = 4;
-
- /* MOV b,REGTMP */
- p = appendp(p);
- p->as = AMOVW;
- p->line = q1->line;
- p->from.type = D_REG;
- p->from.reg = q1->reg;
- if(q1->reg == NREG)
- p->from.reg = q1->to.reg;
- p->to.type = D_REG;
- p->to.reg = REGTMP;
- p->to.offset = 0;
-
- /* CALL appropriate */
- p = appendp(p);
- p->as = ABL;
- p->line = q1->line;
- p->to.type = D_BRANCH;
- p->cond = p;
- switch(o) {
- case ADIV:
- p->cond = prog_div;
- p->to.sym = sym_div;
- break;
- case ADIVU:
- p->cond = prog_divu;
- p->to.sym = sym_divu;
- break;
- case AMOD:
- p->cond = prog_mod;
- p->to.sym = sym_mod;
- break;
- case AMODU:
- p->cond = prog_modu;
- p->to.sym = sym_modu;
- break;
- }
+ LSym *s;
- /* MOV REGTMP, b */
- p = appendp(p);
- p->as = AMOVW;
- p->line = q1->line;
- p->from.type = D_REG;
- p->from.reg = REGTMP;
- p->from.offset = 0;
- p->to.type = D_REG;
- p->to.reg = q1->to.reg;
-
- /* ADD $8,SP */
- p = appendp(p);
- p->as = AADD;
- p->line = q1->line;
- p->from.type = D_CONST;
- p->from.reg = NREG;
- p->from.offset = 8;
- p->reg = NREG;
- p->to.type = D_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 = D_OREG;
- q1->from.reg = REGSP;
- q1->from.offset = 0;
- q1->reg = NREG;
- q1->to.type = D_REG;
- q1->to.reg = REGTMP;
-
- /* SUB $8,SP */
- q1 = appendp(q1);
- q1->as = AMOVW;
- q1->from.type = D_REG;
- q1->from.reg = REGTMP;
- q1->reg = NREG;
- q1->to.type = D_OREG;
- 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 == D_OREG && p->to.reg == REGSP)
- p->spadj = -p->to.offset;
- if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
- p->spadj = -p->from.offset;
- if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
- p->spadj = -p->from.offset;
- break;
- }
- }
- }
-}
-
-static Prog*
-stacksplit(Prog *p, int32 framesize)
-{
- int32 arg;
-
- // MOVW g_stackguard(g), R1
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_OREG;
- p->from.reg = REGG;
- p->to.type = D_REG;
- p->to.reg = 1;
-
- if(framesize <= StackSmall) {
- // small stack: SP < stackguard
- // CMP stackguard, SP
- p = appendp(p);
- p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->reg = REGSP;
- } else if(framesize <= StackBig) {
- // large stack: SP-framesize < stackguard-StackSmall
- // MOVW $-framesize(SP), R2
- // CMP stackguard, R2
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.reg = REGSP;
- p->from.offset = -framesize;
- p->to.type = D_REG;
- p->to.reg = 2;
-
- p = appendp(p);
- p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->reg = 2;
- } 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(p);
- p->as = ACMP;
- p->from.type = D_CONST;
- p->from.offset = (uint32)StackPreempt;
- p->reg = 1;
-
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.reg = REGSP;
- p->from.offset = StackGuard;
- p->to.type = D_REG;
- p->to.reg = 2;
- p->scond = C_SCOND_NE;
-
- p = appendp(p);
- p->as = ASUB;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->to.type = D_REG;
- p->to.reg = 2;
- p->scond = C_SCOND_NE;
-
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.offset = framesize + (StackGuard - StackSmall);
- p->to.type = D_REG;
- p->to.reg = 3;
- p->scond = C_SCOND_NE;
-
- p = appendp(p);
- p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 3;
- p->reg = 2;
- p->scond = C_SCOND_NE;
- }
-
- // MOVW.LS $framesize, R1
- p = appendp(p);
- p->as = AMOVW;
- p->scond = C_SCOND_LS;
- p->from.type = D_CONST;
- p->from.offset = framesize;
- p->to.type = D_REG;
- p->to.reg = 1;
-
- // MOVW.LS $args, R2
- p = appendp(p);
- p->as = AMOVW;
- p->scond = C_SCOND_LS;
- p->from.type = D_CONST;
- arg = cursym->text->to.offset2;
- if(arg == 1) // special marker for known 0
- arg = 0;
- if(arg&3)
- diag("misaligned argument size in stack split");
- p->from.offset = arg;
- p->to.type = D_REG;
- p->to.reg = 2;
-
- // MOVW.LS R14, R3
- p = appendp(p);
- p->as = AMOVW;
- p->scond = C_SCOND_LS;
- p->from.type = D_REG;
- p->from.reg = REGLINK;
- p->to.type = D_REG;
- p->to.reg = 3;
-
- // BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted
- p = appendp(p);
- p->as = ABL;
- p->scond = C_SCOND_LS;
- p->to.type = D_BRANCH;
- p->to.sym = symmorestack;
- p->cond = pmorestack;
-
- // BLS start
- p = appendp(p);
- p->as = ABLS;
- p->to.type = D_BRANCH;
- p->cond = cursym->text->link;
-
- return p;
-}
-
-static void
-sigdiv(char *n)
-{
- Sym *s;
-
- s = lookup(n, 0);
- if(s->type == STEXT)
- if(s->sig == 0)
- s->sig = SIGNINTERN;
-}
-
-void
-divsig(void)
-{
- sigdiv("_div");
- sigdiv("_divu");
- sigdiv("_mod");
- sigdiv("_modu");
-}
-
-void
-initdiv(void)
-{
- Sym *s2, *s3, *s4, *s5;
-
- if(prog_div != P)
- return;
- sym_div = s2 = lookup("_div", 0);
- sym_divu = s3 = lookup("_divu", 0);
- sym_mod = s4 = lookup("_mod", 0);
- sym_modu = s5 = lookup("_modu", 0);
- prog_div = s2->text;
- prog_divu = s3->text;
- prog_mod = s4->text;
- prog_modu = s5->text;
- if(prog_div == P) {
- diag("undefined: %s", s2->name);
- prog_div = cursym->text;
- }
- if(prog_divu == P) {
- diag("undefined: %s", s3->name);
- prog_divu = cursym->text;
- }
- if(prog_mod == P) {
- diag("undefined: %s", s4->name);
- prog_mod = cursym->text;
- }
- if(prog_modu == P) {
- diag("undefined: %s", s5->name);
- prog_modu = cursym->text;
- }
-}
-
-void
-nocache(Prog *p)
-{
- p->optab = 0;
- p->from.class = 0;
- p->to.class = 0;
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->addstacksplit(ctxt, s);
}
diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c
index 80f5787dc..86a0ece2e 100644
--- a/src/cmd/5l/obj.c
+++ b/src/cmd/5l/obj.c
@@ -30,120 +30,24 @@
// Reading object files.
-#define EXTERN
#include "l.h"
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/dwarf.h"
#include <ar.h>
-#ifndef DEFAULT
-#define DEFAULT '9'
-#endif
-
-char *noname = "<none>";
-char *thestring = "arm";
-
-Header headers[] = {
- "noheader", Hnoheader,
- "risc", Hrisc,
- "plan9", Hplan9x32,
- "ixp1200", Hixp1200,
- "ipaq", Hipaq,
- "linux", Hlinux,
- "freebsd", Hfreebsd,
- "netbsd", Hnetbsd,
- 0, 0
-};
-
-/*
- * -Hrisc -T0x10005000 -R4 is aif for risc os
- * -Hplan9 -T4128 -R4096 is plan9 format
- * -Hixp1200 is IXP1200 (raw)
- * -Hipaq -T0xC0008010 -R1024 is ipaq
- * -Hlinux -Tx -Rx is linux elf
- * -Hfreebsd is freebsd elf
- * -Hnetbsd is netbsd elf
- */
+char *thestring = "arm";
+LinkArch *thelinkarch = &linkarm;
void
-main(int argc, char *argv[])
+linkarchinit(void)
{
- char *p;
- Sym *s;
-
- Binit(&bso, 1, OWRITE);
- listinit();
- nerrors = 0;
- outfile = "5.out";
- HEADTYPE = -1;
- INITTEXT = -1;
- INITDAT = -1;
- INITRND = -1;
- INITENTRY = 0;
- linkmode = LinkAuto;
- nuxiinit();
-
- p = getgoarm();
- if(p != nil)
- goarm = atoi(p);
- else
- goarm = 6;
- if(goarm == 5)
- debug['F'] = 1;
-
- flagcount("1", "use alternate profiling code", &debug['1']);
- flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
- flagstr("E", "sym: entry symbol", &INITENTRY);
- flagint32("D", "addr: data address", &INITDAT);
- flagcount("G", "debug pseudo-ops", &debug['G']);
- flagfn1("I", "interp: set ELF interp", setinterp);
- flagfn1("L", "dir: add dir to library path", Lflag);
- flagfn1("H", "head: header type", setheadtype);
- flagcount("K", "add stack underflow checks", &debug['K']);
- flagcount("M", "disable software div/mod", &debug['M']);
- flagcount("O", "print pc-line tables", &debug['O']);
- flagcount("P", "debug code generation", &debug['P']);
- flagint32("R", "rnd: address rounding", &INITRND);
- flagint32("T", "addr: text address", &INITTEXT);
- flagfn0("V", "print version and exit", doversion);
- flagcount("W", "disassemble input", &debug['W']);
- flagfn2("X", "name value: define string data", addstrdata);
- flagcount("Z", "clear stack frame on entry", &debug['Z']);
- flagcount("a", "disassemble output", &debug['a']);
- flagcount("c", "dump call graph", &debug['c']);
- flagcount("d", "disable dynamic executable", &debug['d']);
- flagstr("extld", "linker to run in external mode", &extld);
- flagstr("extldflags", "flags for external linker", &extldflags);
- flagcount("f", "ignore version mismatch", &debug['f']);
- flagcount("g", "disable go package data checks", &debug['g']);
- flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
- flagstr("k", "sym: set field tracking symbol", &tracksym);
- flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
- flagcount("n", "dump symbol table", &debug['n']);
- flagstr("o", "outfile: set output file", &outfile);
- flagcount("p", "insert profiling code", &debug['p']);
- flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
- flagcount("race", "enable race detector", &flag_race);
- flagcount("s", "disable symbol table", &debug['s']);
- flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
- flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
- flagcount("u", "reject unsafe packages", &debug['u']);
- flagcount("v", "print link trace", &debug['v']);
- flagcount("w", "disable DWARF generation", &debug['w']);
-
- flagparse(&argc, &argv, usage);
-
- if(argc != 1)
- usage();
-
- if(flag_shared)
- linkmode = LinkExternal;
-
- mywhatsys();
+}
- if(HEADTYPE == -1)
- HEADTYPE = headtype(goos);
+void
+archinit(void)
+{
+ LSym *s;
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash.
@@ -158,34 +62,15 @@ main(int argc, char *argv[])
sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
break;
case Hlinux:
+ case Hfreebsd:
break;
}
- libinit();
-
switch(HEADTYPE) {
default:
diag("unknown -H option");
errorexit();
- case Hnoheader: /* no header */
- HEADR = 0L;
- if(INITTEXT == -1)
- INITTEXT = 0;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 4;
- break;
- case Hrisc: /* aif for risc os */
- HEADR = 128L;
- if(INITTEXT == -1)
- INITTEXT = 0x10005000 + HEADR;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 4;
- break;
- case Hplan9x32: /* plan 9 */
+ case Hplan9: /* plan 9 */
HEADR = 32L;
if(INITTEXT == -1)
INITTEXT = 4128;
@@ -194,30 +79,11 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
- case Hixp1200: /* boot for IXP1200 */
- HEADR = 0L;
- if(INITTEXT == -1)
- INITTEXT = 0x0;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 4;
- break;
- case Hipaq: /* boot for ipaq */
- HEADR = 16L;
- if(INITTEXT == -1)
- INITTEXT = 0xC0008010;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 1024;
- break;
case Hlinux: /* arm elf */
case Hfreebsd:
case Hnetbsd:
+ case Hnacl:
debug['d'] = 0; // with dynamic linking
- tlsoffset = -8; // hardcoded number, first 4-byte word for g, and then 4-byte word for m
- // this number is known to ../../pkg/runtime/rt0_*_arm.s
elfinit();
HEADR = ELFRESERVE;
if(INITTEXT == -1)
@@ -231,578 +97,9 @@ main(int argc, char *argv[])
if(INITDAT != 0 && INITRND != 0)
print("warning: -D0x%ux is ignored because of -R0x%ux\n",
INITDAT, INITRND);
- if(debug['v'])
- Bprint(&bso, "HEADER = -H0x%d -T0x%ux -D0x%ux -R0x%ux\n",
- HEADTYPE, INITTEXT, INITDAT, INITRND);
- Bflush(&bso);
- zprg.as = AGOK;
- zprg.scond = 14;
- zprg.reg = NREG;
- zprg.from.name = D_NONE;
- zprg.from.type = D_NONE;
- zprg.from.reg = NREG;
- zprg.to = zprg.from;
- buildop();
- histgen = 0;
- pc = 0;
- dtype = 4;
-
- version = 0;
- cbp = buf.cbuf;
- cbc = sizeof(buf.cbuf);
// embed goarm to runtime.goarm
- s = lookup("runtime.goarm", 0);
- s->dupok = 1;
- adduint8(s, goarm);
-
- addlibpath("command line", "command line", argv[0], "main");
- loadlib();
-
- // mark some functions that are only referenced after linker code editing
- if(debug['F'])
- mark(rlookup("_sfloat", 0));
- mark(lookup("runtime.read_tls_fallback", 0));
- deadcode();
- if(textp == nil) {
- diag("no code");
- errorexit();
- }
-
- patch();
- if(debug['p'])
- if(debug['1'])
- doprof1();
- else
- doprof2();
- doelf();
- follow();
- softfloat();
- // 5l -Z means zero the stack frame on entry.
- // This slows down function calls but can help avoid
- // false positives in garbage collection.
- if(debug['Z'])
- dozerostk();
- noops(); // generate stack split prolog, handle div/mod, etc.
- dostkcheck();
- span();
- addexport();
- // textaddress() functionality is handled in span()
- pclntab();
- symtab();
- dodata();
- address();
- doweak();
- reloc();
- asmb();
- undef();
- hostlink();
-
- if(debug['c'])
- print("ARM size = %d\n", armsize);
- if(debug['v']) {
- Bprint(&bso, "%5.2f cpu time\n", cputime());
- Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
- Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
- }
- Bflush(&bso);
- errorexit();
-}
-
-static Sym*
-zsym(char *pn, Biobuf *f, Sym *h[])
-{
- int o;
-
- o = BGETC(f);
- if(o == 0)
- return S;
- if(o < 0 || o >= NSYM || h[o] == nil)
- mangle(pn);
- return h[o];
-}
-
-static void
-zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[])
-{
- int i, c;
- int32 l;
- Sym *s;
- Auto *u;
-
- a->type = BGETC(f);
- a->reg = BGETC(f);
- c = BGETC(f);
- if(c < 0 || c > NSYM){
- print("sym out of range: %d\n", c);
- BPUTC(f, ALAST+1);
- return;
- }
- a->sym = h[c];
- a->name = BGETC(f);
- adrgotype = zsym(pn, f, h);
-
- if((schar)a->reg < 0 || a->reg > NREG) {
- print("register out of range %d\n", a->reg);
- BPUTC(f, ALAST+1);
- return; /* force real diagnostic */
- }
-
- if(a->type == D_CONST || a->type == D_OCONST) {
- if(a->name == D_EXTERN || a->name == D_STATIC) {
- s = a->sym;
- if(s != S && (s->type == STEXT || s->type == SCONST || s->type == SXREF)) {
- if(0 && !s->fnptr && s->name[0] != '.')
- print("%s used as function pointer\n", s->name);
- s->fnptr = 1; // over the top cos of SXREF
- }
- }
- }
-
- switch(a->type) {
- default:
- print("unknown type %d\n", a->type);
- BPUTC(f, ALAST+1);
- return; /* force real diagnostic */
-
- case D_NONE:
- case D_REG:
- case D_FREG:
- case D_PSR:
- case D_FPCR:
- break;
-
- case D_REGREG:
- case D_REGREG2:
- a->offset = BGETC(f);
- break;
-
- case D_CONST2:
- a->offset2 = BGETLE4(f); // fall through
- case D_BRANCH:
- case D_OREG:
- case D_CONST:
- case D_OCONST:
- case D_SHIFT:
- a->offset = BGETLE4(f);
- break;
-
- case D_SCONST:
- a->sval = mal(NSNAME);
- Bread(f, a->sval, NSNAME);
- break;
-
- case D_FCONST:
- a->ieee.l = BGETLE4(f);
- a->ieee.h = BGETLE4(f);
- break;
- }
- s = a->sym;
- if(s == S)
- return;
- i = a->name;
- if(i != D_AUTO && i != D_PARAM) {
- if(s && adrgotype)
- s->gotype = adrgotype;
- return;
- }
-
- l = a->offset;
- for(u=curauto; u; u=u->link)
- if(u->asym == s)
- if(u->type == i) {
- if(u->aoffset > l)
- u->aoffset = l;
- if(adrgotype)
- u->gotype = adrgotype;
- return;
- }
-
- u = mal(sizeof(Auto));
- u->link = curauto;
- curauto = u;
- u->asym = s;
- u->aoffset = l;
- u->type = i;
- u->gotype = adrgotype;
-}
-
-void
-nopout(Prog *p)
-{
- p->as = ANOP;
- p->from.type = D_NONE;
- p->to.type = D_NONE;
-}
-
-void
-ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
-{
- int32 ipc;
- Prog *p;
- Sym *h[NSYM], *s;
- int v, o, r, skip;
- uint32 sig;
- char *name;
- int ntext;
- int32 eof;
- char src[1024], *x;
- Prog *lastp;
-
- lastp = nil;
- ntext = 0;
- eof = Boffset(f) + len;
- src[0] = 0;
- pn = estrdup(pn); // we keep it in Sym* references
-
-newloop:
- memset(h, 0, sizeof(h));
- version++;
- histfrogp = 0;
- ipc = pc;
- skip = 0;
-
-loop:
- if(f->state == Bracteof || Boffset(f) >= eof)
- goto eof;
- o = BGETC(f);
- if(o == Beof)
- goto eof;
-
- if(o <= AXXX || o >= ALAST) {
- diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
- print(" probably not a .5 file\n");
- errorexit();
- }
- if(o == ANAME || o == ASIGNAME) {
- sig = 0;
- if(o == ASIGNAME)
- sig = BGETLE4(f);
- v = BGETC(f); /* type */
- o = BGETC(f); /* sym */
- r = 0;
- if(v == D_STATIC)
- r = version;
- name = Brdline(f, '\0');
- if(name == nil) {
- if(Blinelen(f) > 0) {
- fprint(2, "%s: name too long\n", pn);
- errorexit();
- }
- goto eof;
- }
- x = expandpkg(name, pkg);
- s = lookup(x, r);
- if(x != name)
- free(x);
-
- if(sig != 0){
- if(s->sig != 0 && s->sig != sig)
- diag("incompatible type signatures %ux(%s) and %ux(%s) for %s", s->sig, s->file, sig, pn, s->name);
- s->sig = sig;
- s->file = pn;
- }
-
- if(debug['W'])
- print(" ANAME %s\n", s->name);
- if(o < 0 || o >= nelem(h)) {
- fprint(2, "%s: mangled input file\n", pn);
- errorexit();
- }
- h[o] = s;
- if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
- s->type = SXREF;
- if(v == D_FILE) {
- if(s->type != SFILE) {
- histgen++;
- s->type = SFILE;
- s->value = histgen;
- }
- if(histfrogp < MAXHIST) {
- histfrog[histfrogp] = s;
- histfrogp++;
- } else
- collapsefrog(s);
- dwarfaddfrag(s->value, s->name);
- }
- goto loop;
- }
-
- p = mal(sizeof(Prog));
- p->as = o;
- p->scond = BGETC(f);
- p->reg = BGETC(f);
- p->line = BGETLE4(f);
-
- zaddr(pn, f, &p->from, h);
- fromgotype = adrgotype;
- zaddr(pn, f, &p->to, h);
-
- if(p->as != ATEXT && p->as != AGLOBL && p->reg > NREG)
- diag("register out of range %A %d", p->as, p->reg);
-
- p->link = P;
- p->cond = P;
-
- if(debug['W'])
- print("%P\n", p);
-
- switch(o) {
- case AHISTORY:
- if(p->to.offset == -1) {
- addlib(src, pn);
- histfrogp = 0;
- goto loop;
- }
- if(src[0] == '\0')
- copyhistfrog(src, sizeof src);
- addhist(p->line, D_FILE); /* 'z' */
- if(p->to.offset)
- addhist(p->to.offset, D_FILE1); /* 'Z' */
- savehist(p->line, p->to.offset);
- histfrogp = 0;
- goto loop;
-
- case AEND:
- histtoauto();
- if(cursym != nil && cursym->text)
- cursym->autom = curauto;
- curauto = 0;
- cursym = nil;
- if(Boffset(f) == eof)
- return;
- goto newloop;
-
- case AGLOBL:
- s = p->from.sym;
- if(s == S) {
- diag("GLOBL must have a name\n%P", p);
- errorexit();
- }
- if(s->type == 0 || s->type == SXREF) {
- s->type = SBSS;
- s->value = 0;
- }
- if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
- diag("redefinition: %s\n%P", s->name, p);
- s->type = SBSS;
- s->value = 0;
- }
- if(p->to.offset > s->size)
- s->size = p->to.offset;
- if(p->reg & DUPOK)
- s->dupok = 1;
- if(p->reg & RODATA)
- s->type = SRODATA;
- else if(p->reg & NOPTR)
- s->type = SNOPTRBSS;
- break;
-
- case ADATA:
- // Assume that AGLOBL comes after ADATA.
- // If we've seen an AGLOBL that said this sym was DUPOK,
- // ignore any more ADATA we see, which must be
- // redefinitions.
- s = p->from.sym;
- if(s->dupok) {
-// if(debug['v'])
-// Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
- goto loop;
- }
- if(s->file == nil)
- s->file = pn;
- else if(s->file != pn) {
- diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
- errorexit();
- }
- savedata(s, p, pn);
- unmal(p, sizeof *p);
- break;
-
- case AGOK:
- diag("unknown opcode\n%P", p);
- p->pc = pc;
- pc++;
- break;
-
- case ATYPE:
- if(skip)
- goto casedef;
- pc++;
- goto loop;
-
- case ATEXT:
- if(cursym != nil && cursym->text) {
- histtoauto();
- cursym->autom = curauto;
- curauto = 0;
- }
- s = p->from.sym;
- if(s == S) {
- diag("TEXT must have a name\n%P", p);
- errorexit();
- }
- cursym = s;
- if(s->type != 0 && s->type != SXREF && (p->reg & DUPOK)) {
- skip = 1;
- goto casedef;
- }
- if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
- /* redefinition, so file has probably been seen before */
- if(debug['v'])
- Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name);
- return;
- }
- skip = 0;
- if(s->type != 0 && s->type != SXREF)
- diag("redefinition: %s\n%P", s->name, p);
- if(etextp)
- etextp->next = s;
- else
- textp = s;
- if(fromgotype) {
- if(s->gotype && s->gotype != fromgotype)
- diag("%s: type mismatch for %s", pn, s->name);
- s->gotype = fromgotype;
- }
- etextp = s;
- p->align = 4;
- autosize = (p->to.offset+3L) & ~3L;
- p->to.offset = autosize;
- autosize += 4;
- s->type = STEXT;
- s->hist = gethist();
- s->text = p;
- s->value = pc;
- s->args = p->to.offset2;
- lastp = p;
- p->pc = pc;
- pc++;
- break;
-
- case ASUB:
- if(p->from.type == D_CONST)
- if(p->from.name == D_NONE)
- if(p->from.offset < 0) {
- p->from.offset = -p->from.offset;
- p->as = AADD;
- }
- goto casedef;
-
- case AADD:
- if(p->from.type == D_CONST)
- if(p->from.name == D_NONE)
- if(p->from.offset < 0) {
- p->from.offset = -p->from.offset;
- p->as = ASUB;
- }
- goto casedef;
-
- 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:
- goto casedef;
-
- case AMOVF:
- if(skip)
- goto casedef;
-
- if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0 &&
- (chipzero(&p->from.ieee) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
- /* size sb 9 max */
- sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
- s = lookup(literal, 0);
- if(s->type == 0) {
- s->type = SRODATA;
- adduint32(s, ieeedtof(&p->from.ieee));
- s->reachable = 0;
- }
- p->from.type = D_OREG;
- p->from.sym = s;
- p->from.name = D_EXTERN;
- p->from.offset = 0;
- }
- goto casedef;
-
- case AMOVD:
- if(skip)
- goto casedef;
-
- if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0 &&
- (chipzero(&p->from.ieee) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
- /* size sb 18 max */
- sprint(literal, "$%ux.%ux",
- p->from.ieee.l, p->from.ieee.h);
- s = lookup(literal, 0);
- if(s->type == 0) {
- s->type = SRODATA;
- adduint32(s, p->from.ieee.l);
- adduint32(s, p->from.ieee.h);
- s->reachable = 0;
- }
- p->from.type = D_OREG;
- p->from.sym = s;
- p->from.name = D_EXTERN;
- p->from.offset = 0;
- }
- goto casedef;
-
- default:
- casedef:
- if(skip)
- nopout(p);
- p->pc = pc;
- pc++;
- if(p->to.type == D_BRANCH)
- p->to.offset += ipc;
- if(lastp == nil) {
- if(p->as != ANOP)
- diag("unexpected instruction: %P", p);
- break;
- }
- lastp->link = p;
- lastp = p;
- break;
- }
- goto loop;
-
-eof:
- diag("truncated object file: %s", pn);
-}
-
-Prog*
-prg(void)
-{
- Prog *p;
-
- p = mal(sizeof(Prog));
- *p = zprg;
- return p;
-}
-
-Prog*
-appendp(Prog *q)
-{
- Prog *p;
-
- p = prg();
- p->link = q->link;
- q->link = p;
- p->line = q->line;
- return p;
+ s = linklookup(ctxt, "runtime.goarm", 0);
+ s->type = SRODATA;
+ adduint8(ctxt, s, ctxt->goarm);
}
diff --git a/src/cmd/5l/optab.c b/src/cmd/5l/optab.c
deleted file mode 100644
index 3d05d6d09..000000000
--- a/src/cmd/5l/optab.c
+++ /dev/null
@@ -1,277 +0,0 @@
-// Inferno utils/5l/optab.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/optab.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 "l.h"
-
-Optab optab[] =
-{
- /* struct Optab:
- OPCODE, from, prog->reg, to, type,size,param,flag */
- { ATEXT, C_ADDR, C_NONE, C_LCON, 0, 0, 0 },
- { ATEXT, C_ADDR, C_REG, C_LCON, 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 },
-
- { 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 },
-
- { AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 },
-};
diff --git a/src/cmd/5l/pass.c b/src/cmd/5l/pass.c
deleted file mode 100644
index cd8897989..000000000
--- a/src/cmd/5l/pass.c
+++ /dev/null
@@ -1,409 +0,0 @@
-// Inferno utils/5l/pass.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/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 "l.h"
-#include "../ld/lib.h"
-
-static void xfol(Prog*, Prog**);
-
-Prog*
-brchain(Prog *p)
-{
- int i;
-
- for(i=0; i<20; i++) {
- if(p == P || p->as != AB)
- return p;
- p = p->cond;
- }
- return P;
-}
-
-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;
- }
- diag("unknown relation: %s", anames[a]);
- return a;
-}
-
-void
-follow(void)
-{
- Prog *firstp, *lastp;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f follow\n", cputime());
- Bflush(&bso);
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- firstp = prg();
- lastp = firstp;
- xfol(cursym->text, &lastp);
- lastp->link = nil;
- cursym->text = firstp->link;
- }
-}
-
-static void
-xfol(Prog *p, Prog **last)
-{
- Prog *q, *r;
- int a, i;
-
-loop:
- if(p == P)
- return;
- a = p->as;
- if(a == AB) {
- q = p->cond;
- if(q != P && 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 == 14) || a == ARFE || a == AUNDEF)
- goto copy;
- if(q->cond == P || (q->cond->mark&FOLL))
- continue;
- if(a != ABEQ && a != ABNE)
- continue;
- copy:
- for(;;) {
- r = prg();
- *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 == 14) || a == ARFE || a == AUNDEF)
- return;
- r->as = ABNE;
- if(a == ABNE)
- r->as = ABEQ;
- r->cond = p->link;
- r->link = p->cond;
- if(!(r->link->mark&FOLL))
- xfol(r->link, last);
- if(!(r->cond->mark&FOLL))
- print("can't happen 2\n");
- return;
- }
- }
- a = AB;
- q = prg();
- q->as = a;
- q->line = p->line;
- q->to.type = D_BRANCH;
- q->to.offset = p->pc;
- q->cond = p;
- p = q;
- }
- p->mark |= FOLL;
- (*last)->link = p;
- *last = p;
- if(a == AB || (a == ARET && p->scond == 14) || a == ARFE || a == AUNDEF){
- return;
- }
- if(p->cond != P)
- if(a != ABL && a != ABX && p->link != P) {
- q = brchain(p->link);
- if(a != ATEXT && a != ABCASE)
- if(q != P && (q->mark&FOLL)) {
- p->as = relinv(a);
- p->link = p->cond;
- p->cond = q;
- }
- xfol(p->link, last);
- q = brchain(p->cond);
- if(q == P)
- q = p->cond;
- if(q->mark&FOLL) {
- p->cond = q;
- return;
- }
- p = q;
- goto loop;
- }
- p = p->link;
- goto loop;
-}
-
-void
-patch(void)
-{
- int32 c, vexit;
- Prog *p, *q;
- Sym *s;
- int a;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f patch\n", cputime());
- Bflush(&bso);
- mkfwd();
- s = lookup("exit", 0);
- vexit = s->value;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- a = p->as;
- if((a == ABL || a == ABX || a == AB || a == ARET) &&
- p->to.type != D_BRANCH && p->to.sym != S) {
- s = p->to.sym;
- if(s->text == nil)
- continue;
- switch(s->type&SMASK) {
- default:
- diag("undefined: %s", s->name);
- s->type = STEXT;
- s->value = vexit;
- continue; // avoid more error messages
- case STEXT:
- p->to.offset = s->value;
- p->to.type = D_BRANCH;
- p->cond = s->text;
- continue;
- }
- }
- if(p->to.type != D_BRANCH)
- continue;
- c = p->to.offset;
- for(q = cursym->text; q != P;) {
- if(c == q->pc)
- break;
- if(q->forwd != P && c >= q->forwd->pc)
- q = q->forwd;
- else
- q = q->link;
- }
- if(q == P) {
- diag("branch out of range %d\n%P", c, p);
- p->to.type = D_NONE;
- }
- p->cond = q;
- }
- }
- if(flag_shared) {
- s = lookup("init_array", 0);
- s->type = SINITARR;
- s->reachable = 1;
- s->hide = 1;
- addaddr(s, lookup(INITENTRY, 0));
- }
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- if(p->cond != P) {
- p->cond = brloop(p->cond);
- if(p->cond != P)
- if(p->to.type == D_BRANCH)
- p->to.offset = p->cond->pc;
- }
- }
- }
-}
-
-Prog*
-brloop(Prog *p)
-{
- Prog *q;
- int c;
-
- for(c=0; p!=P;) {
- if(p->as != AB)
- return p;
- q = p->cond;
- if(q <= p) {
- c++;
- if(q == p || c > 5000)
- break;
- }
- p = q;
- }
- return P;
-}
-
-int32
-atolwhex(char *s)
-{
- int32 n;
- int f;
-
- n = 0;
- f = 0;
- while(*s == ' ' || *s == '\t')
- s++;
- if(*s == '-' || *s == '+') {
- if(*s++ == '-')
- f = 1;
- while(*s == ' ' || *s == '\t')
- s++;
- }
- if(s[0]=='0' && s[1]){
- if(s[1]=='x' || s[1]=='X'){
- s += 2;
- for(;;){
- if(*s >= '0' && *s <= '9')
- n = n*16 + *s++ - '0';
- else if(*s >= 'a' && *s <= 'f')
- n = n*16 + *s++ - 'a' + 10;
- else if(*s >= 'A' && *s <= 'F')
- n = n*16 + *s++ - 'A' + 10;
- else
- break;
- }
- } else
- while(*s >= '0' && *s <= '7')
- n = n*8 + *s++ - '0';
- } else
- while(*s >= '0' && *s <= '9')
- n = n*10 + *s++ - '0';
- if(f)
- n = -n;
- return n;
-}
-
-int32
-rnd(int32 v, int32 r)
-{
- int32 c;
-
- if(r <= 0)
- return v;
- v += r - 1;
- c = v % r;
- if(c < 0)
- c += r;
- v -= c;
- return v;
-}
-
-void
-dozerostk(void)
-{
- Prog *p, *pl;
- int32 autoffset;
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(cursym->text == nil || cursym->text->link == nil)
- continue;
- p = cursym->text;
- autoffset = p->to.offset;
- if(autoffset < 0)
- autoffset = 0;
- if(autoffset && !(p->reg&NOSPLIT)) {
- // MOVW $4(R13), R1
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.reg = 13;
- p->from.offset = 4;
- p->to.type = D_REG;
- p->to.reg = 1;
-
- // MOVW $n(R13), R2
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.reg = 13;
- p->from.offset = 4 + autoffset;
- p->to.type = D_REG;
- p->to.reg = 2;
-
- // MOVW $0, R3
- p = appendp(p);
- p->as = AMOVW;
- p->from.type = D_CONST;
- p->from.offset = 0;
- p->to.type = D_REG;
- p->to.reg = 3;
-
- // L:
- // MOVW.P R3, 0(R1) +4
- // CMP R1, R2
- // BNE L
- p = pl = appendp(p);
- p->as = AMOVW;
- p->from.type = D_REG;
- p->from.reg = 3;
- p->to.type = D_OREG;
- p->to.reg = 1;
- p->to.offset = 4;
- p->scond |= C_PBIT;
-
- p = appendp(p);
- p->as = ACMP;
- p->from.type = D_REG;
- p->from.reg = 1;
- p->reg = 2;
-
- p = appendp(p);
- p->as = ABNE;
- p->to.type = D_BRANCH;
- p->cond = pl;
- }
- }
-}
diff --git a/src/cmd/5l/prof.c b/src/cmd/5l/prof.c
deleted file mode 100644
index 225a52435..000000000
--- a/src/cmd/5l/prof.c
+++ /dev/null
@@ -1,211 +0,0 @@
-// Inferno utils/5l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/obj.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.
-
-// Profiling.
-
-#include "l.h"
-#include "../ld/lib.h"
-
-void
-doprof1(void)
-{
-#ifdef NOTDEF // TODO(rsc)
- Sym *s;
- int32 n;
- Prog *p, *q;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f profile 1\n", cputime());
- Bflush(&bso);
- s = lookup("__mcount", 0);
- n = 1;
- for(p = firstp->link; p != P; p = p->link) {
- if(p->as == ATEXT) {
- q = prg();
- q->line = p->line;
- q->link = datap;
- datap = q;
- q->as = ADATA;
- q->from.type = D_OREG;
- q->from.name = D_EXTERN;
- q->from.offset = n*4;
- q->from.sym = s;
- q->reg = 4;
- q->to = p->from;
- q->to.type = D_CONST;
-
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = AMOVW;
- p->from.type = D_OREG;
- p->from.name = D_EXTERN;
- p->from.sym = s;
- p->from.offset = n*4 + 4;
- p->to.type = D_REG;
- p->to.reg = REGTMP;
-
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = AADD;
- p->from.type = D_CONST;
- p->from.offset = 1;
- p->to.type = D_REG;
- p->to.reg = REGTMP;
-
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = AMOVW;
- p->from.type = D_REG;
- p->from.reg = REGTMP;
- p->to.type = D_OREG;
- p->to.name = D_EXTERN;
- p->to.sym = s;
- p->to.offset = n*4 + 4;
-
- n += 2;
- continue;
- }
- }
- q = prg();
- q->line = 0;
- q->link = datap;
- datap = q;
-
- q->as = ADATA;
- q->from.type = D_OREG;
- q->from.name = D_EXTERN;
- q->from.sym = s;
- q->reg = 4;
- q->to.type = D_CONST;
- q->to.offset = n;
-
- s->type = SBSS;
- s->value = n*4;
-#endif
-}
-
-void
-doprof2(void)
-{
- Sym *s2, *s4;
- Prog *p, *q, *ps2, *ps4;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f profile 2\n", cputime());
- Bflush(&bso);
- s2 = lookup("_profin", 0);
- s4 = lookup("_profout", 0);
- if(s2->type != STEXT || s4->type != STEXT) {
- diag("_profin/_profout not defined");
- return;
- }
- ps2 = P;
- ps4 = P;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
- if(cursym == s2) {
- ps2 = p;
- p->reg = 1;
- }
- if(cursym == s4) {
- ps4 = p;
- p->reg = 1;
- }
- }
- for(cursym = textp; cursym != nil; cursym = cursym->next)
- for(p = cursym->text; p != P; p = p->link) {
- if(p->as == ATEXT) {
- if(p->reg & NOPROF) {
- for(;;) {
- q = p->link;
- if(q == P)
- break;
- if(q->as == ATEXT)
- break;
- p = q;
- }
- continue;
- }
-
- /*
- * BL profin, R2
- */
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = ABL;
- p->to.type = D_BRANCH;
- p->cond = ps2;
- p->to.sym = s2;
-
- continue;
- }
- if(p->as == ARET) {
- /*
- * RET
- */
- q = prg();
- q->as = ARET;
- q->from = p->from;
- q->to = p->to;
- q->link = p->link;
- p->link = q;
-
- /*
- * BL profout
- */
- p->as = ABL;
- p->from = zprg.from;
- p->to = zprg.to;
- p->to.type = D_BRANCH;
- p->cond = ps4;
- p->to.sym = s4;
-
- p = q;
-
- continue;
- }
- }
-}
diff --git a/src/cmd/5l/softfloat.c b/src/cmd/5l/softfloat.c
deleted file mode 100644
index de6481c71..000000000
--- a/src/cmd/5l/softfloat.c
+++ /dev/null
@@ -1,91 +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 "l.h"
-#include "../ld/lib.h"
-
-// Software floating point.
-
-void
-softfloat(void)
-{
- Prog *p, *next, *psfloat;
- Sym *symsfloat;
- int wasfloat;
-
- if(!debug['F'])
- return;
-
- symsfloat = lookup("_sfloat", 0);
- psfloat = P;
- if(symsfloat->type == STEXT)
- psfloat = symsfloat->text;
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- wasfloat = 0;
- for(p = cursym->text; p != P; p = p->link)
- if(p->cond != P)
- p->cond->mark |= LABEL;
- for(p = cursym->text; p != P; p = p->link) {
- switch(p->as) {
- case AMOVW:
- if(p->to.type == D_FREG || p->from.type == D_FREG)
- 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 (psfloat == P)
- diag("floats used with _sfloat not defined");
- if (!wasfloat || (p->mark&LABEL)) {
- next = prg();
- *next = *p;
-
- // BL _sfloat(SB)
- *p = zprg;
- p->link = next;
- p->as = ABL;
- p->to.type = D_BRANCH;
- p->to.sym = symsfloat;
- p->cond = psfloat;
- p->line = next->line;
-
- p = next;
- wasfloat = 1;
- }
- break;
-
- notsoft:
- wasfloat = 0;
- }
- }
- }
-}
diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c
deleted file mode 100644
index e7cc0b4b1..000000000
--- a/src/cmd/5l/span.c
+++ /dev/null
@@ -1,937 +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 "l.h"
-#include "../ld/lib.h"
-
-static struct {
- uint32 start;
- uint32 size;
- uint32 extra;
-} pool;
-
-int checkpool(Prog*, int);
-int flushpool(Prog*, int, int);
-
-int
-isbranch(Prog *p)
-{
- int as = p->as;
- return (as >= ABEQ && as <= ABLE) || as == AB || as == ABL || as == ABX;
-}
-
-static int
-scan(Prog *op, Prog *p, int c)
-{
- Prog *q;
-
- for(q = op->link; q != p && q != P; q = q->link){
- q->pc = c;
- c += oplook(q)->size;
- nocache(q);
- }
- return c;
-}
-
-/* size of a case statement including jump table */
-static int32
-casesz(Prog *p)
-{
- int jt = 0;
- int32 n = 0;
- Optab *o;
-
- for( ; p != P; p = p->link){
- if(p->as == ABCASE)
- jt = 1;
- else if(jt)
- break;
- o = oplook(p);
- n += o->size;
- }
- return n;
-}
-
-void
-span(void)
-{
- Prog *p, *op;
- Optab *o;
- int m, bflag, i, v;
- int32 c, otxt, out[6];
- Section *sect;
- uchar *bp;
- Sym *sub, *gmsym;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f span\n", cputime());
- Bflush(&bso);
-
- sect = addsection(&segtext, ".text", 05);
- lookup("text", 0)->sect = sect;
- lookup("etext", 0)->sect = sect;
-
- bflag = 0;
- c = INITTEXT;
- otxt = c;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- cursym->sect = sect;
- p = cursym->text;
- if(p == P || p->link == P) { // handle external functions and ELF section symbols
- if(cursym->type & SSUB)
- continue;
- if(cursym->align != 0)
- c = rnd(c, cursym->align);
- cursym->value = 0;
- for(sub = cursym; sub != S; sub = sub->sub) {
- sub->value += c;
- for(p = sub->text; p != P; p = p->link)
- p->pc += sub->value;
- }
- c += cursym->size;
- continue;
- }
- p->pc = c;
- cursym->value = c;
-
- autosize = p->to.offset + 4;
- if(p->from.sym != S)
- p->from.sym->value = c;
- /* need passes to resolve branches */
- if(c-otxt >= 1L<<17)
- bflag = 1;
- otxt = c;
-
- for(op = p, p = p->link; p != P; op = p, p = p->link) {
- curp = p;
- p->pc = c;
- o = oplook(p);
- m = o->size;
- // must check literal pool here in case p generates many instructions
- if(blitrl){
- if(checkpool(op, p->as == ACASE ? casesz(p) : m))
- c = p->pc = scan(op, p, c);
- }
- if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) {
- diag("zero-width instruction\n%P", p);
- continue;
- }
- switch(o->flag & (LFROM|LTO|LPOOL)) {
- case LFROM:
- addpool(p, &p->from);
- break;
- case LTO:
- addpool(p, &p->to);
- break;
- case LPOOL:
- if ((p->scond&C_SCOND) == 14)
- flushpool(p, 0, 0);
- break;
- }
- if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == 14)
- flushpool(p, 0, 0);
- c += m;
- }
- if(blitrl){
- if(checkpool(op, 0))
- c = scan(op, P, c);
- }
- cursym->size = c - cursym->value;
- }
-
- /*
- * 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.
- */
- while(bflag) {
- if(debug['v'])
- Bprint(&bso, "%5.2f span1\n", cputime());
- bflag = 0;
- c = INITTEXT;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(!cursym->text || !cursym->text->link)
- continue;
- cursym->value = c;
- for(p = cursym->text; p != P; p = p->link) {
- curp = p;
- p->pc = c;
- o = oplook(p);
-/* very large branches
- if(o->type == 6 && p->cond) {
- otxt = p->cond->pc - c;
- if(otxt < 0)
- otxt = -otxt;
- if(otxt >= (1L<<17) - 10) {
- q = prg();
- q->link = p->link;
- p->link = q;
- q->as = AB;
- q->to.type = D_BRANCH;
- q->cond = p->cond;
- p->cond = q;
- q = prg();
- q->link = p->link;
- p->link = q;
- q->as = AB;
- q->to.type = D_BRANCH;
- q->cond = q->link->link;
- bflag = 1;
- }
- }
- */
- m = o->size;
- if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) {
- if(p->as == ATEXT) {
- autosize = p->to.offset + 4;
- if(p->from.sym != S)
- p->from.sym->value = c;
- continue;
- }
- diag("zero-width instruction\n%P", p);
- continue;
- }
- c += m;
- }
- cursym->size = c - cursym->value;
- }
- }
-
- c = rnd(c, 8);
-
- /*
- * 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.
- */
- gmsym = S;
- if(linkmode == LinkExternal)
- gmsym = lookup("runtime.tlsgm", 0);
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
- if(p == P || p->link == P)
- continue;
- autosize = p->to.offset + 4;
- symgrow(cursym, cursym->size);
-
- bp = cursym->p;
- for(p = p->link; p != P; p = p->link) {
- pc = p->pc;
- curp = p;
- o = oplook(p);
- asmout(p, o, out, gmsym);
- for(i=0; i<o->size/4; i++) {
- v = out[i];
- *bp++ = v;
- *bp++ = v>>8;
- *bp++ = v>>16;
- *bp++ = v>>24;
- }
- }
- }
- sect->vaddr = INITTEXT;
- sect->len = c - INITTEXT;
-}
-
-/*
- * 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.
- */
-int
-checkpool(Prog *p, int sz)
-{
- if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0)
- return flushpool(p, 1, 0);
- else if(p->link == P)
- return flushpool(p, 2, 0);
- return 0;
-}
-
-int
-flushpool(Prog *p, int skip, int force)
-{
- Prog *q;
-
- if(blitrl) {
- if(skip){
- if(0 && skip==1)print("note: flush literal pool at %ux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
- q = prg();
- q->as = AB;
- q->to.type = D_BRANCH;
- q->cond = p->link;
- q->link = blitrl;
- q->line = p->line;
- blitrl = q;
- }
- else if(!force && (p->pc+pool.size-pool.start < 2048))
- return 0;
- elitrl->link = p->link;
- p->link = 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(blitrl) {
- blitrl->line = p->line;
- blitrl = blitrl->link;
- }
- blitrl = 0; /* BUG: should refer back to values until out-of-range */
- elitrl = 0;
- pool.size = 0;
- pool.start = 0;
- pool.extra = 0;
- return 1;
- }
- return 0;
-}
-
-void
-addpool(Prog *p, Adr *a)
-{
- Prog *q, t;
- int c;
-
- c = aclass(a);
-
- t = zprg;
- t.as = AWORD;
-
- switch(c) {
- default:
- t.to = *a;
- if(flag_shared && t.to.sym != S)
- 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 = D_CONST;
- t.to.offset = instoffset;
- break;
- }
-
- if(t.pcrel == P) {
- for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */
- if(q->pcrel == P && memcmp(&q->to, &t.to, sizeof(t.to)) == 0) {
- p->cond = q;
- return;
- }
- }
-
- q = prg();
- *q = t;
- q->pc = pool.size;
-
- if(blitrl == P) {
- blitrl = q;
- pool.start = p->pc;
- q->align = 4;
- } else
- elitrl->link = q;
- elitrl = q;
- pool.size += 4;
-
- p->cond = q;
-}
-
-void
-xdefine(char *p, int t, int32 v)
-{
- Sym *s;
-
- s = lookup(p, 0);
- s->type = t;
- s->value = v;
- s->reachable = 1;
- s->special = 1;
-}
-
-int32
-regoff(Adr *a)
-{
-
- instoffset = 0;
- aclass(a);
- return instoffset;
-}
-
-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;
-}
-
-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;
-}
-
-int
-immfloat(int32 v)
-{
- return (v & 0xC03) == 0; /* offset will fit in floating-point load/store */
-}
-
-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;
-}
-
-int32
-symaddr(Sym *s)
-{
- if(!s->reachable)
- diag("unreachable symbol in symaddr - %s", s->name);
- return s->value;
-}
-
-int
-aclass(Adr *a)
-{
- Sym *s;
- int t;
-
- switch(a->type) {
- case D_NONE:
- return C_NONE;
-
- case D_REG:
- return C_REG;
-
- case D_REGREG:
- return C_REGREG;
-
- case D_REGREG2:
- return C_REGREG2;
-
- case D_SHIFT:
- return C_SHIFT;
-
- case D_FREG:
- return C_FREG;
-
- case D_FPCR:
- return C_FCR;
-
- case D_OREG:
- switch(a->name) {
- case D_EXTERN:
- case D_STATIC:
- if(a->sym == 0 || a->sym->name == 0) {
- print("null sym external\n");
- print("%D\n", a);
- return C_GOK;
- }
- instoffset = 0; // s.b. unused but just in case
- return C_ADDR;
-
- case D_AUTO:
- instoffset = autosize + a->offset;
- t = immaddr(instoffset);
- if(t){
- if(immhalf(instoffset))
- return immfloat(t) ? C_HFAUTO : C_HAUTO;
- if(immfloat(t))
- return C_FAUTO;
- return C_SAUTO;
- }
- return C_LAUTO;
-
- case D_PARAM:
- instoffset = autosize + a->offset + 4L;
- t = immaddr(instoffset);
- if(t){
- if(immhalf(instoffset))
- return immfloat(t) ? C_HFAUTO : C_HAUTO;
- if(immfloat(t))
- return C_FAUTO;
- return C_SAUTO;
- }
- return C_LAUTO;
- case D_NONE:
- instoffset = a->offset;
- t = immaddr(instoffset);
- if(t) {
- if(immhalf(instoffset)) /* n.b. that it will also satisfy immrot */
- return immfloat(t) ? C_HFOREG : C_HOREG;
- if(immfloat(t))
- return C_FOREG; /* n.b. that it will also satisfy immrot */
- t = immrot(instoffset);
- if(t)
- return C_SROREG;
- if(immhalf(instoffset))
- return C_HOREG;
- return C_SOREG;
- }
- t = immrot(instoffset);
- if(t)
- return C_ROREG;
- return C_LOREG;
- }
- return C_GOK;
-
- case D_PSR:
- return C_PSR;
-
- case D_OCONST:
- switch(a->name) {
- case D_EXTERN:
- case D_STATIC:
- instoffset = 0; // s.b. unused but just in case
- return C_ADDR;
- }
- return C_GOK;
-
- case D_FCONST:
- if(chipzero(&a->ieee) >= 0)
- return C_ZFCON;
- if(chipfloat(&a->ieee) >= 0)
- return C_SFCON;
- return C_LFCON;
-
- case D_CONST:
- case D_CONST2:
- switch(a->name) {
-
- case D_NONE:
- instoffset = a->offset;
- if(a->reg != NREG)
- goto aconsize;
-
- t = immrot(instoffset);
- if(t)
- return C_RCON;
- t = immrot(~instoffset);
- if(t)
- return C_NCON;
- return C_LCON;
-
- case D_EXTERN:
- case D_STATIC:
- s = a->sym;
- if(s == S)
- break;
- instoffset = 0; // s.b. unused but just in case
- return C_LCONADDR;
-
- case D_AUTO:
- instoffset = autosize + a->offset;
- goto aconsize;
-
- case D_PARAM:
- instoffset = autosize + a->offset + 4L;
- aconsize:
- t = immrot(instoffset);
- if(t)
- return C_RACON;
- return C_LACON;
- }
- return C_GOK;
-
- case D_BRANCH:
- return C_SBRA;
- }
- return C_GOK;
-}
-
-Optab*
-oplook(Prog *p)
-{
- int a1, a2, a3, r;
- char *c1, *c3;
- Optab *o, *e;
-
- a1 = p->optab;
- if(a1)
- return optab+(a1-1);
- a1 = p->from.class;
- if(a1 == 0) {
- a1 = aclass(&p->from) + 1;
- p->from.class = a1;
- }
- a1--;
- a3 = p->to.class;
- if(a3 == 0) {
- a3 = aclass(&p->to) + 1;
- p->to.class = a3;
- }
- a3--;
- a2 = C_NONE;
- if(p->reg != NREG)
- a2 = C_REG;
- r = p->as;
- o = oprange[r].start;
- if(o == 0) {
- a1 = opcross[repop[r]][a1][a2][a3];
- if(a1) {
- p->optab = a1+1;
- return optab+a1;
- }
- o = oprange[r].stop; /* just generate an error */
- }
- if(debug['O']) {
- print("oplook %A %O %O %O\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;
- }
- diag("illegal combination %A %O %O %O, %d %d",
- p->as, a1, a2, a3, p->from.type, p->to.type);
- prasm(p);
- if(o == 0)
- o = optab;
- return o;
-}
-
-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;
-}
-
-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;
-}
-
-void
-buildop(void)
-{
- 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(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:
- diag("unknown op in build: %A", r);
- errorexit();
- 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 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:
- break;
- }
- }
-}
-
-/*
-void
-buildrep(int x, int as)
-{
- Opcross *p;
- Optab *e, *s, *o;
- int a1, a2, a3, n;
-
- if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) {
- diag("assumptions fail in buildrep");
- errorexit();
- }
- repop[as] = x;
- p = (opcross + x);
- s = oprange[as].start;
- e = oprange[as].stop;
- for(o=e-1; o>=s; o--) {
- n = o-optab;
- for(a2=0; a2<2; a2++) {
- if(a2) {
- if(o->a2 == C_NONE)
- continue;
- } else
- if(o->a2 != C_NONE)
- continue;
- for(a1=0; a1<32; a1++) {
- if(!xcmp[a1][o->a1])
- continue;
- for(a3=0; a3<32; a3++)
- if(xcmp[a3][o->a3])
- (*p)[a1][a2][a3] = n;
- }
- }
- }
- oprange[as].start = 0;
-}
-*/
diff --git a/src/cmd/6a/a.h b/src/cmd/6a/a.h
index 5c7868070..b3fb0bb19 100644
--- a/src/cmd/6a/a.h
+++ b/src/cmd/6a/a.h
@@ -29,9 +29,9 @@
// THE SOFTWARE.
#include <bio.h>
+#include <link.h>
#include "../6l/6.out.h"
-
#ifndef EXTERN
#define EXTERN extern
#endif
@@ -45,10 +45,8 @@
typedef struct Sym Sym;
typedef struct Ref Ref;
-typedef struct Gen Gen;
typedef struct Io Io;
-typedef struct Hist Hist;
-typedef struct Gen2 Gen2;
+typedef struct Addr2 Addr2;
#define MAXALIGN 7
#define FPCHIP 1
@@ -97,36 +95,11 @@ struct Io
};
#define I ((Io*)0)
-EXTERN struct
-{
- Sym* sym;
- short type;
-} h[NSYM];
-
-struct Gen
-{
- double dval;
- char sval[8];
- vlong offset;
- Sym* sym;
- short type;
- short index;
- short scale;
-};
-struct Gen2
-{
- Gen from;
- Gen to;
-};
-
-struct Hist
+struct Addr2
{
- Hist* link;
- char* name;
- int32 line;
- vlong offset;
+ Addr from;
+ Addr to;
};
-#define H ((Hist*)0)
enum
{
@@ -136,14 +109,11 @@ enum
CPREPROC,
};
-
-EXTERN char debug[256];
+EXTERN int debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
-EXTERN Hist* ehist;
EXTERN int newflag;
-EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
@@ -154,10 +124,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
-EXTERN Gen nullgen;
+EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
-EXTERN char* pathname;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
@@ -167,6 +136,8 @@ EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
+EXTERN Link* ctxt;
+EXTERN Biobuf bstdout;
void* alloc(int32);
void* allocn(void*, int32, int32);
@@ -187,12 +158,11 @@ void cinit(void);
void checkscale(int);
void pinit(char*);
void cclean(void);
-int isreg(Gen*);
-void outcode(int, Gen2*);
+int isreg(Addr*);
+void outcode(int, Addr2*);
void outhist(void);
-void zaddr(Gen*, int);
+void zaddr(Addr*, int);
void zname(char*, int, int);
-void ieeedtod(Ieee*, double);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
diff --git a/src/cmd/6a/a.y b/src/cmd/6a/a.y
index ed72916b2..6fd491067 100644
--- a/src/cmd/6a/a.y
+++ b/src/cmd/6a/a.y
@@ -40,8 +40,8 @@
vlong lval;
double dval;
char sval[8];
- Gen gen;
- Gen2 gen2;
+ Addr addr;
+ Addr2 addr2;
}
%left '|'
%left '^'
@@ -58,10 +58,10 @@
%token <sval> LSCONST LSP
%token <sym> LNAME LLAB LVAR
%type <lval> con con2 expr pointer offset
-%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem
-%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim
-%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
-%type <gen2> spec10 spec11 spec12 spec13
+%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
+%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
+%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
+%type <addr2> spec10 spec11 spec12 spec13
%%
prog:
| prog
@@ -367,14 +367,12 @@ rel:
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
- $$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
- $$.sym = $1;
$$.offset = $1->value + $2;
}
@@ -444,31 +442,31 @@ imm:
{
$$ = nullgen;
$$.type = D_SCONST;
- memcpy($$.sval, $2, sizeof($$.sval));
+ memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = $2;
+ $$.u.dval = $2;
}
| '$' '(' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = $3;
+ $$.u.dval = $3;
}
| '$' '(' '-' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = -$4;
+ $$.u.dval = -$4;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = -$3;
+ $$.u.dval = -$3;
}
mem:
@@ -572,14 +570,14 @@ nam:
{
$$ = nullgen;
$$.type = $4;
- $$.sym = $1;
+ $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_STATIC;
- $$.sym = $1;
+ $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}
diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c
index ab34e8220..167e6b6c1 100644
--- a/src/cmd/6a/lex.c
+++ b/src/cmd/6a/lex.c
@@ -57,56 +57,80 @@ pathchar(void)
return '/';
}
+int
+Lconv(Fmt *fp)
+{
+ return linklinefmt(ctxt, fp);
+}
+
+void
+dodef(char *p)
+{
+ if(nDlist%8 == 0)
+ Dlist = allocn(Dlist, nDlist*sizeof(char *),
+ 8*sizeof(char *));
+ Dlist[nDlist++] = p;
+}
+
+LinkArch* thelinkarch = &linkamd64;
+
+void
+usage(void)
+{
+ print("usage: %ca [options] file.c...\n", thechar);
+ flagprint(1);
+ errorexit();
+}
+
void
main(int argc, char *argv[])
{
char *p;
- int c;
thechar = '6';
thestring = "amd64";
+ // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+ // but not other values.
+ p = getgoarch();
+ if(strncmp(p, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
+ if(strcmp(p, "amd64p32") == 0)
+ thelinkarch = &linkamd64p32;
+
+ ctxt = linknew(thelinkarch);
+ ctxt->diag = yyerror;
+ ctxt->bso = &bstdout;
+ Binit(&bstdout, 1, OWRITE);
+ listinit6();
+ fmtinstall('L', Lconv);
+
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
cinit();
outfile = 0;
setinclude(".");
- ARGBEGIN {
- default:
- c = ARGC();
- if(c >= 0 && c < sizeof(debug))
- debug[c] = 1;
- break;
-
- case 'o':
- outfile = ARGF();
- break;
+
+ flagfn1("D", "name[=value]: add #define", dodef);
+ flagfn1("I", "dir: add dir to include path", setinclude);
+ flagcount("S", "print assembly and machine code", &debug['S']);
+ flagcount("m", "debug preprocessor macros", &debug['m']);
+ flagstr("o", "file: set output file", &outfile);
+ flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
- case 'D':
- p = ARGF();
- if(p) {
- if (nDlist%8 == 0)
- Dlist = allocn(Dlist, nDlist*sizeof(char *),
- 8*sizeof(char *));
- Dlist[nDlist++] = p;
- }
- break;
+ flagparse(&argc, &argv, usage);
+ ctxt->debugasm = debug['S'];
- case 'I':
- p = ARGF();
- setinclude(p);
- break;
- } ARGEND
- if(*argv == 0) {
- print("usage: %ca [-options] file.s\n", thechar);
- errorexit();
- }
+ if(argc < 1)
+ usage();
if(argc > 1){
print("can't assemble multiple files\n");
errorexit();
}
+
if(assemble(argv[0]))
errorexit();
+ Bflush(&bstdout);
exits(0);
}
@@ -145,30 +169,22 @@ assemble(char *file)
errorexit();
}
Binit(&obuf, of, OWRITE);
+ Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
+ Bprint(&obuf, "!\n");
- pass = 1;
- pinit(file);
-
- Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
-
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- if(nerrors) {
+ for(pass = 1; pass <= 2; pass++) {
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
cclean();
- return nerrors;
+ if(nerrors)
+ return nerrors;
}
- Bprint(&obuf, "\n!\n");
-
- pass = 2;
- outhist();
- pinit(file);
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- cclean();
- return nerrors;
+ writeobj(ctxt, &obuf);
+ Bflush(&obuf);
+ return 0;
}
struct
@@ -313,6 +329,7 @@ struct
"TR5", LBREG, D_TR+5,
"TR6", LBREG, D_TR+6,
"TR7", LBREG, D_TR+7,
+ "TLS", LSREG, D_TLS,
"AAA", LTYPE0, AAAA,
"AAD", LTYPE0, AAAD,
@@ -503,6 +520,7 @@ struct
"MOVLQZX", LTYPE3, AMOVLQZX,
"MOVNTIL", LTYPE3, AMOVNTIL,
"MOVNTIQ", LTYPE3, AMOVNTIQ,
+ "MOVQL", LTYPE3, AMOVQL,
"MOVWLSX", LTYPE3, AMOVWLSX,
"MOVWLZX", LTYPE3, AMOVWLZX,
"MOVWQSX", LTYPE3, AMOVWQSX,
@@ -1031,15 +1049,8 @@ cinit(void)
Sym *s;
int i;
- nullgen.sym = S;
- nullgen.offset = 0;
- if(FPCHIP)
- nullgen.dval = 0;
- for(i=0; i<sizeof(nullgen.sval); i++)
- nullgen.sval[i] = 0;
nullgen.type = D_NONE;
nullgen.index = D_NONE;
- nullgen.scale = 0;
nerrors = 0;
iostack = I;
@@ -1055,13 +1066,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
-
- pathname = allocn(pathname, 0, 100);
- if(getwd(pathname, 99) == 0) {
- pathname = allocn(pathname, 100, 900);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
- }
}
void
@@ -1089,255 +1093,43 @@ syminit(Sym *s)
void
cclean(void)
{
- Gen2 g2;
+ Addr2 g2;
g2.from = nullgen;
g2.to = nullgen;
outcode(AEND, &g2);
- Bflush(&obuf);
}
-void
-zname(char *n, int t, int s)
-{
-
- BPUTLE2(&obuf, ANAME); /* as(2) */
- BPUTC(&obuf, t); /* type */
- BPUTC(&obuf, s); /* sym */
- while(*n) {
- BPUTC(&obuf, *n);
- n++;
- }
- BPUTC(&obuf, 0);
-}
+static Prog *lastpc;
void
-zaddr(Gen *a, int s)
+outcode(int a, Addr2 *g2)
{
- int32 l;
- int i, t;
- char *n;
- Ieee e;
-
- t = 0;
- if(a->index != D_NONE || a->scale != 0)
- t |= T_INDEX;
- if(a->offset != 0) {
- t |= T_OFFSET;
- l = a->offset;
- if((vlong)l != a->offset)
- t |= T_64;
- }
- if(s != 0)
- t |= T_SYM;
-
- switch(a->type) {
- default:
- t |= T_TYPE;
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- case D_NONE:
- break;
- }
- BPUTC(&obuf, t);
-
- if(t & T_INDEX) { /* implies index, scale */
- BPUTC(&obuf, a->index);
- BPUTC(&obuf, a->scale);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- BPUTLE4(&obuf, l);
- if(t & T_64) {
- l = a->offset>>32;
- BPUTLE4(&obuf, l);
- }
- }
- if(t & T_SYM) /* implies sym */
- BPUTC(&obuf, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->dval);
- l = e.l;
- BPUTLE4(&obuf, l);
- l = e.h;
- BPUTLE4(&obuf, l);
- return;
- }
- if(t & T_SCONST) {
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(&obuf, *n);
- n++;
- }
- return;
- }
- if(t & T_TYPE)
- BPUTC(&obuf, a->type);
-}
-
-void
-outcode(int a, Gen2 *g2)
-{
- int sf, st, t;
- Sym *s;
-
+ Prog *p;
+ Plist *pl;
+
if(pass == 1)
goto out;
-jackpot:
- sf = 0;
- s = g2->from.sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = g2->from.type;
- if(t == D_ADDR)
- t = g2->from.index;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = g2->to.sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = g2->to.type;
- if(t == D_ADDR)
- t = g2->to.index;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- BPUTLE2(&obuf, a);
- BPUTLE4(&obuf, stmtline);
- zaddr(&g2->from, sf);
- zaddr(&g2->to, st);
+ p = malloc(sizeof *p);
+ memset(p, 0, sizeof *p);
+ p->as = a;
+ p->lineno = stmtline;
+ p->from = g2->from;
+ p->to = g2->to;
+ p->pc = pc;
+
+ if(lastpc == nil) {
+ pl = linknewplist(ctxt);
+ pl->firstpc = p;
+ } else
+ lastpc->link = p;
+ lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
-void
-outhist(void)
-{
- Gen g;
- Hist *h;
- char *p, *q, *op, c;
- int n;
- char *tofree;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
-
- g = nullgen;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p != nil && goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- op = 0;
- if(systemtype(Windows) && p && p[1] == ':'){
- c = p[2];
- } else if(p && p[0] != c && h->offset == 0 && pathname){
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname;
- c = p[2];
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = strchr(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- BPUTLE2(&obuf, ANAME);
- BPUTC(&obuf, D_FILE); /* type */
- BPUTC(&obuf, 1); /* sym */
- BPUTC(&obuf, '<');
- Bwrite(&obuf, p, n);
- BPUTC(&obuf, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- g.offset = h->offset;
-
- BPUTLE2(&obuf, AHISTORY);
- BPUTLE4(&obuf, h->line);
- zaddr(&nullgen, 0);
- zaddr(&g, 0);
-
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
#include "../cc/lexbody"
#include "../cc/macbody"
diff --git a/src/cmd/6a/y.tab.c b/src/cmd/6a/y.tab.c
index 3e5058b9d..a4f0f74cc 100644
--- a/src/cmd/6a/y.tab.c
+++ b/src/cmd/6a/y.tab.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -44,7 +47,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -52,51 +55,11 @@
/* Pure parsers. */
#define YYPURE 0
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
/* Using locations. */
#define YYLSP_NEEDED 0
-/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 31 "a.y"
-
-#include <u.h>
-#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../pkg/runtime/funcdata.h"
-
-
-/* Line 268 of yacc.c */
-#line 80 "y.tab.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -180,36 +143,60 @@
+/* Copy the first part of user declarations. */
+#line 31 "a.y"
+
+#include <u.h>
+#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
+#include <libc.h>
+#include "a.h"
+#include "../../pkg/runtime/funcdata.h"
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c */
#line 38 "a.y"
-
+{
Sym *sym;
vlong lval;
double dval;
char sval[8];
- Gen gen;
- Gen2 gen2;
-
-
-
-/* Line 293 of yacc.c */
-#line 201 "y.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+ Addr addr;
+ Addr2 addr2;
+}
+/* Line 193 of yacc.c. */
+#line 187 "y.tab.c"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
+
/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 213 "y.tab.c"
+/* Line 216 of yacc.c. */
+#line 200 "y.tab.c"
#ifdef short
# undef short
@@ -284,14 +271,14 @@ typedef short int yytype_int16;
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static int
-YYID (int yyi)
+YYID (int i)
#else
static int
-YYID (yyi)
- int yyi;
+YYID (i)
+ int i;
#endif
{
- return yyi;
+ return i;
}
#endif
@@ -312,11 +299,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# endif
@@ -339,24 +326,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+# if (defined __cplusplus && ! defined _STDLIB_H \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@@ -372,9 +359,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- yytype_int16 yyss_alloc;
- YYSTYPE yyvs_alloc;
-};
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -385,27 +372,6 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
@@ -423,7 +389,24 @@ union yyalloc
while (YYID (0))
# endif
# endif
-#endif /* !YYCOPY_NEEDED */
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
@@ -564,13 +547,13 @@ static const yytype_uint16 yyrline[] =
166, 173, 178, 183, 190, 198, 203, 211, 216, 223,
224, 227, 232, 242, 247, 257, 262, 267, 274, 282,
292, 296, 303, 308, 316, 325, 336, 337, 340, 341,
- 342, 346, 350, 351, 354, 355, 358, 364, 373, 382,
- 387, 392, 397, 402, 407, 412, 418, 426, 432, 443,
- 449, 455, 461, 467, 475, 476, 479, 485, 491, 497,
- 503, 512, 521, 530, 535, 540, 548, 558, 562, 571,
- 578, 587, 590, 594, 600, 601, 605, 608, 609, 613,
- 617, 621, 625, 631, 636, 641, 646, 653, 654, 658,
- 662, 666, 670, 674, 678, 682, 686, 690
+ 342, 346, 350, 351, 354, 355, 358, 364, 372, 380,
+ 385, 390, 395, 400, 405, 410, 416, 424, 430, 441,
+ 447, 453, 459, 465, 473, 474, 477, 483, 489, 495,
+ 501, 510, 519, 528, 533, 538, 546, 556, 560, 569,
+ 576, 585, 588, 592, 598, 599, 603, 606, 607, 611,
+ 615, 619, 623, 629, 634, 639, 644, 651, 652, 656,
+ 660, 664, 668, 672, 676, 680, 684, 688
};
#endif
@@ -586,12 +569,11 @@ static const char *const yytname[] =
"LTYPEF", "LCONST", "LFP", "LPC", "LSB", "LBREG", "LLREG", "LSREG",
"LFREG", "LMREG", "LXREG", "LFCONST", "LSCONST", "LSP", "LNAME", "LLAB",
"LVAR", "':'", "';'", "'='", "','", "'('", "')'", "'$'", "'~'",
- "$accept", "prog", "$@1", "line", "$@2", "$@3", "inst", "nonnon",
- "rimrem", "remrim", "rimnon", "nonrem", "nonrel", "spec1", "spec2",
- "spec3", "spec4", "spec5", "spec6", "spec7", "spec8", "spec9", "spec10",
- "spec11", "spec12", "spec13", "rem", "rom", "rim", "rel", "reg", "imm2",
- "imm", "mem", "omem", "nmem", "nam", "offset", "pointer", "con", "con2",
- "expr", 0
+ "$accept", "prog", "@1", "line", "@2", "@3", "inst", "nonnon", "rimrem",
+ "remrim", "rimnon", "nonrem", "nonrel", "spec1", "spec2", "spec3",
+ "spec4", "spec5", "spec6", "spec7", "spec8", "spec9", "spec10", "spec11",
+ "spec12", "spec13", "rem", "rom", "rim", "rel", "reg", "imm2", "imm",
+ "mem", "omem", "nmem", "nam", "offset", "pointer", "con", "con2", "expr", 0
};
#endif
@@ -647,8 +629,8 @@ static const yytype_uint8 yyr2[] =
3, 3, 3, 4, 4, 3, 3, 3
};
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@@ -739,7 +721,8 @@ static const yytype_int16 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF, syntax error. */
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint16 yytable[] =
{
@@ -802,12 +785,6 @@ static const yytype_uint16 yytable[] =
177
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-94))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
static const yytype_int16 yycheck[] =
{
10, 10, 13, 13, 10, 13, 66, 67, 10, 10,
@@ -915,18 +892,9 @@ static const yytype_uint8 yystos[] =
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
+ Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
#define YYRECOVERING() (!!yyerrstatus)
@@ -936,6 +904,7 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@@ -977,10 +946,19 @@ while (YYID (0))
#endif
-/* This macro is provided for backward compatibility. */
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
#endif
@@ -1084,20 +1062,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -1131,11 +1106,11 @@ yy_reduce_print (yyvsp, yyrule)
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ fprintf (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
);
- YYFPRINTF (stderr, "\n");
+ fprintf (stderr, "\n");
}
}
@@ -1172,6 +1147,7 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
+
#if YYERROR_VERBOSE
@@ -1274,142 +1250,115 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return 2 if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- /* Internationalized format string. */
- const char *yyformat = 0;
- /* Arguments of yyformat. */
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
- int yycount = 0;
-
- /* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yytoken != YYEMPTY)
- {
- int yyn = yypact[*yyssp];
- yyarg[yycount++] = yytname[yytoken];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
- }
- }
+ int yyn = yypact[yystate];
- switch (yycount)
- {
-# define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
- }
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return 1;
- }
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyformat += 2;
- }
- else
- {
- yyp++;
- yyformat++;
- }
- }
- return 0;
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
}
#endif /* YYERROR_VERBOSE */
+
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@@ -1441,9 +1390,10 @@ yydestruct (yymsg, yytype, yyvaluep)
break;
}
}
-
+
/* Prevent warnings from -Wmissing-prototypes. */
+
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
@@ -1459,16 +1409,18 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
-/* The lookahead symbol. */
+
+/* The look-ahead symbol. */
int yychar;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
int yynerrs;
+
/*----------.
| yyparse. |
`----------*/
@@ -1495,37 +1447,14 @@ yyparse ()
#endif
#endif
{
- int yystate;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
-
- /* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
-
- YYSIZE_T yystacksize;
-
+
+ int yystate;
int yyn;
int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
@@ -1533,28 +1462,51 @@ yyparse ()
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yystacksize = YYINITDEPTH;
-
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
+ yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
+
yyssp = yyss;
yyvsp = yyvs;
@@ -1584,6 +1536,7 @@ yyparse ()
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
+
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
@@ -1591,6 +1544,7 @@ yyparse ()
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
+
&yystacksize);
yyss = yyss1;
@@ -1613,8 +1567,9 @@ yyparse ()
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@@ -1625,6 +1580,7 @@ yyparse ()
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
+
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
@@ -1634,9 +1590,6 @@ yyparse ()
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
- if (yystate == YYFINAL)
- YYACCEPT;
-
goto yybackup;
/*-----------.
@@ -1645,16 +1598,16 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
+ look-ahead token if we need one and don't already have one. */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
+ if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -1680,22 +1633,26 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yytable_value_is_error (yyn))
- goto yyerrlab;
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
- /* Shift the lookahead token. */
+ /* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the shifted token. */
- yychar = YYEMPTY;
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
@@ -1735,8 +1692,6 @@ yyreduce:
switch (yyn)
{
case 3:
-
-/* Line 1806 of yacc.c */
#line 68 "a.y"
{
stmtline = lineno;
@@ -1744,8 +1699,6 @@ yyreduce:
break;
case 5:
-
-/* Line 1806 of yacc.c */
#line 75 "a.y"
{
if((yyvsp[(1) - (2)].sym)->value != pc)
@@ -1755,8 +1708,6 @@ yyreduce:
break;
case 7:
-
-/* Line 1806 of yacc.c */
#line 82 "a.y"
{
(yyvsp[(1) - (2)].sym)->type = LLAB;
@@ -1765,8 +1716,6 @@ yyreduce:
break;
case 12:
-
-/* Line 1806 of yacc.c */
#line 93 "a.y"
{
(yyvsp[(1) - (3)].sym)->type = LVAR;
@@ -1775,8 +1724,6 @@ yyreduce:
break;
case 13:
-
-/* Line 1806 of yacc.c */
#line 98 "a.y"
{
if((yyvsp[(1) - (3)].sym)->value != (yyvsp[(3) - (3)].lval))
@@ -1786,622 +1733,490 @@ yyreduce:
break;
case 14:
-
-/* Line 1806 of yacc.c */
#line 103 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 15:
-
-/* Line 1806 of yacc.c */
#line 104 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 16:
-
-/* Line 1806 of yacc.c */
#line 105 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 17:
-
-/* Line 1806 of yacc.c */
#line 106 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 18:
-
-/* Line 1806 of yacc.c */
#line 107 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 19:
-
-/* Line 1806 of yacc.c */
#line 108 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 20:
-
-/* Line 1806 of yacc.c */
#line 109 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 21:
-
-/* Line 1806 of yacc.c */
#line 110 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 22:
-
-/* Line 1806 of yacc.c */
#line 111 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 23:
-
-/* Line 1806 of yacc.c */
#line 112 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 24:
-
-/* Line 1806 of yacc.c */
#line 113 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 25:
-
-/* Line 1806 of yacc.c */
#line 114 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 26:
-
-/* Line 1806 of yacc.c */
#line 115 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 27:
-
-/* Line 1806 of yacc.c */
#line 116 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 28:
-
-/* Line 1806 of yacc.c */
#line 117 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 29:
-
-/* Line 1806 of yacc.c */
#line 118 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 30:
-
-/* Line 1806 of yacc.c */
#line 119 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 31:
-
-/* Line 1806 of yacc.c */
#line 120 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 32:
-
-/* Line 1806 of yacc.c */
#line 121 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 33:
-
-/* Line 1806 of yacc.c */
#line 124 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = nullgen;
}
break;
case 34:
-
-/* Line 1806 of yacc.c */
#line 129 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = nullgen;
}
break;
case 35:
-
-/* Line 1806 of yacc.c */
#line 136 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 36:
-
-/* Line 1806 of yacc.c */
#line 143 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 37:
-
-/* Line 1806 of yacc.c */
#line 150 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (2)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 38:
-
-/* Line 1806 of yacc.c */
#line 155 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (1)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 39:
-
-/* Line 1806 of yacc.c */
#line 162 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
}
break;
case 40:
-
-/* Line 1806 of yacc.c */
#line 167 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(1) - (1)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
}
break;
case 41:
-
-/* Line 1806 of yacc.c */
#line 174 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
}
break;
case 42:
-
-/* Line 1806 of yacc.c */
#line 179 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(1) - (1)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
}
break;
case 43:
-
-/* Line 1806 of yacc.c */
#line 184 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 44:
-
-/* Line 1806 of yacc.c */
#line 191 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).from.scale = (yyvsp[(3) - (5)].lval);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
}
break;
case 45:
-
-/* Line 1806 of yacc.c */
#line 199 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 46:
-
-/* Line 1806 of yacc.c */
#line 204 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).from.scale = (yyvsp[(3) - (5)].lval);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
}
break;
case 47:
-
-/* Line 1806 of yacc.c */
#line 212 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
}
break;
case 48:
-
-/* Line 1806 of yacc.c */
#line 217 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(1) - (1)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
}
break;
case 51:
-
-/* Line 1806 of yacc.c */
#line 228 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 52:
-
-/* Line 1806 of yacc.c */
#line 233 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (5)].gen);
- if((yyval.gen2).from.index != D_NONE)
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
+ if((yyval.addr2).from.index != D_NONE)
yyerror("dp shift with lhs index");
- (yyval.gen2).from.index = (yyvsp[(5) - (5)].lval);
+ (yyval.addr2).from.index = (yyvsp[(5) - (5)].lval);
}
break;
case 53:
-
-/* Line 1806 of yacc.c */
#line 243 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 54:
-
-/* Line 1806 of yacc.c */
#line 248 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (5)].gen);
- if((yyval.gen2).to.index != D_NONE)
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
+ if((yyval.addr2).to.index != D_NONE)
yyerror("dp move with lhs index");
- (yyval.gen2).to.index = (yyvsp[(5) - (5)].lval);
+ (yyval.addr2).to.index = (yyvsp[(5) - (5)].lval);
}
break;
case 55:
-
-/* Line 1806 of yacc.c */
#line 258 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (2)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 56:
-
-/* Line 1806 of yacc.c */
#line 263 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (1)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 57:
-
-/* Line 1806 of yacc.c */
#line 268 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 58:
-
-/* Line 1806 of yacc.c */
#line 275 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (5)].gen);
- (yyval.gen2).to.offset = (yyvsp[(5) - (5)].lval);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
+ (yyval.addr2).to.offset = (yyvsp[(5) - (5)].lval);
}
break;
case 59:
-
-/* Line 1806 of yacc.c */
#line 283 "a.y"
{
- (yyval.gen2).from = (yyvsp[(3) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
- if((yyvsp[(1) - (5)].gen).type != D_CONST)
+ (yyval.addr2).from = (yyvsp[(3) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
+ if((yyvsp[(1) - (5)].addr).type != D_CONST)
yyerror("illegal constant");
- (yyval.gen2).to.offset = (yyvsp[(1) - (5)].gen).offset;
+ (yyval.addr2).to.offset = (yyvsp[(1) - (5)].addr).offset;
}
break;
case 60:
-
-/* Line 1806 of yacc.c */
#line 292 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = nullgen;
}
break;
case 61:
-
-/* Line 1806 of yacc.c */
#line 297 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (1)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 62:
-
-/* Line 1806 of yacc.c */
#line 304 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 63:
-
-/* Line 1806 of yacc.c */
#line 309 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).from.scale = (yyvsp[(3) - (5)].lval);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
}
break;
case 64:
-
-/* Line 1806 of yacc.c */
#line 317 "a.y"
{
- if((yyvsp[(1) - (3)].gen).type != D_CONST || (yyvsp[(3) - (3)].gen).type != D_CONST)
+ if((yyvsp[(1) - (3)].addr).type != D_CONST || (yyvsp[(3) - (3)].addr).type != D_CONST)
yyerror("arguments to PCDATA must be integer constants");
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 65:
-
-/* Line 1806 of yacc.c */
#line 326 "a.y"
{
- if((yyvsp[(1) - (3)].gen).type != D_CONST)
+ if((yyvsp[(1) - (3)].addr).type != D_CONST)
yyerror("index for FUNCDATA must be integer constant");
- if((yyvsp[(3) - (3)].gen).type != D_EXTERN && (yyvsp[(3) - (3)].gen).type != D_STATIC)
+ if((yyvsp[(3) - (3)].addr).type != D_EXTERN && (yyvsp[(3) - (3)].addr).type != D_STATIC)
yyerror("value for FUNCDATA must be symbol reference");
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 70:
-
-/* Line 1806 of yacc.c */
#line 343 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
}
break;
case 71:
-
-/* Line 1806 of yacc.c */
#line 347 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
}
break;
case 76:
-
-/* Line 1806 of yacc.c */
#line 359 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) + pc;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
}
break;
case 77:
-
-/* Line 1806 of yacc.c */
#line 365 "a.y"
{
- (yyval.gen) = nullgen;
+ (yyval.addr) = nullgen;
if(pass == 2)
yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->name);
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).sym = (yyvsp[(1) - (2)].sym);
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 78:
-
-/* Line 1806 of yacc.c */
-#line 374 "a.y"
+#line 373 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).sym = (yyvsp[(1) - (2)].sym);
- (yyval.gen).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
}
break;
case 79:
-
-/* Line 1806 of yacc.c */
-#line 383 "a.y"
+#line 381 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 80:
-
-/* Line 1806 of yacc.c */
-#line 388 "a.y"
+#line 386 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 81:
-
-/* Line 1806 of yacc.c */
-#line 393 "a.y"
+#line 391 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 82:
-
-/* Line 1806 of yacc.c */
-#line 398 "a.y"
+#line 396 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 83:
-
-/* Line 1806 of yacc.c */
-#line 403 "a.y"
+#line 401 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SP;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SP;
}
break;
case 84:
-
-/* Line 1806 of yacc.c */
-#line 408 "a.y"
+#line 406 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 85:
-
-/* Line 1806 of yacc.c */
-#line 413 "a.y"
+#line 411 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 86:
-
-/* Line 1806 of yacc.c */
-#line 419 "a.y"
+#line 417 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_CONST;
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_CONST;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 87:
-
-/* Line 1806 of yacc.c */
-#line 427 "a.y"
+#line 425 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_CONST;
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_CONST;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 88:
-
-/* Line 1806 of yacc.c */
-#line 433 "a.y"
+#line 431 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
- (yyval.gen).index = (yyvsp[(2) - (2)].gen).type;
- (yyval.gen).type = D_ADDR;
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
+ (yyval.addr).index = (yyvsp[(2) - (2)].addr).type;
+ (yyval.addr).type = D_ADDR;
/*
if($2.type == D_AUTO || $2.type == D_PARAM)
yyerror("constant cannot be automatic: %s",
@@ -2411,322 +2226,262 @@ yyreduce:
break;
case 89:
-
-/* Line 1806 of yacc.c */
-#line 444 "a.y"
+#line 442 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SCONST;
- memcpy((yyval.gen).sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.gen).sval));
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SCONST;
+ memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
}
break;
case 90:
-
-/* Line 1806 of yacc.c */
-#line 450 "a.y"
+#line 448 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = (yyvsp[(2) - (2)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
}
break;
case 91:
-
-/* Line 1806 of yacc.c */
-#line 456 "a.y"
+#line 454 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = (yyvsp[(3) - (4)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = (yyvsp[(3) - (4)].dval);
}
break;
case 92:
-
-/* Line 1806 of yacc.c */
-#line 462 "a.y"
+#line 460 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = -(yyvsp[(4) - (5)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = -(yyvsp[(4) - (5)].dval);
}
break;
case 93:
-
-/* Line 1806 of yacc.c */
-#line 468 "a.y"
+#line 466 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = -(yyvsp[(3) - (3)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
}
break;
case 96:
-
-/* Line 1806 of yacc.c */
-#line 480 "a.y"
+#line 478 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_NONE;
- (yyval.gen).offset = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_NONE;
+ (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
}
break;
case 97:
-
-/* Line 1806 of yacc.c */
-#line 486 "a.y"
+#line 484 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (4)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 98:
-
-/* Line 1806 of yacc.c */
-#line 492 "a.y"
+#line 490 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_SP;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_SP;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 99:
-
-/* Line 1806 of yacc.c */
-#line 498 "a.y"
+#line 496 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (4)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 100:
-
-/* Line 1806 of yacc.c */
-#line 504 "a.y"
+#line 502 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_NONE;
- (yyval.gen).offset = (yyvsp[(1) - (6)].lval);
- (yyval.gen).index = (yyvsp[(3) - (6)].lval);
- (yyval.gen).scale = (yyvsp[(5) - (6)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_NONE;
+ (yyval.addr).offset = (yyvsp[(1) - (6)].lval);
+ (yyval.addr).index = (yyvsp[(3) - (6)].lval);
+ (yyval.addr).scale = (yyvsp[(5) - (6)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 101:
-
-/* Line 1806 of yacc.c */
-#line 513 "a.y"
+#line 511 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (9)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (9)].lval);
- (yyval.gen).index = (yyvsp[(6) - (9)].lval);
- (yyval.gen).scale = (yyvsp[(8) - (9)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (9)].lval);
+ (yyval.addr).index = (yyvsp[(6) - (9)].lval);
+ (yyval.addr).scale = (yyvsp[(8) - (9)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 102:
-
-/* Line 1806 of yacc.c */
-#line 522 "a.y"
+#line 520 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (9)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (9)].lval);
- (yyval.gen).index = (yyvsp[(6) - (9)].lval);
- (yyval.gen).scale = (yyvsp[(8) - (9)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (9)].lval);
+ (yyval.addr).index = (yyvsp[(6) - (9)].lval);
+ (yyval.addr).scale = (yyvsp[(8) - (9)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 103:
-
-/* Line 1806 of yacc.c */
-#line 531 "a.y"
+#line 529 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(2) - (3)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(2) - (3)].lval);
}
break;
case 104:
-
-/* Line 1806 of yacc.c */
-#line 536 "a.y"
+#line 534 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_SP;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_SP;
}
break;
case 105:
-
-/* Line 1806 of yacc.c */
-#line 541 "a.y"
+#line 539 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_NONE;
- (yyval.gen).index = (yyvsp[(2) - (5)].lval);
- (yyval.gen).scale = (yyvsp[(4) - (5)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_NONE;
+ (yyval.addr).index = (yyvsp[(2) - (5)].lval);
+ (yyval.addr).scale = (yyvsp[(4) - (5)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 106:
-
-/* Line 1806 of yacc.c */
-#line 549 "a.y"
+#line 547 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(2) - (8)].lval);
- (yyval.gen).index = (yyvsp[(5) - (8)].lval);
- (yyval.gen).scale = (yyvsp[(7) - (8)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(2) - (8)].lval);
+ (yyval.addr).index = (yyvsp[(5) - (8)].lval);
+ (yyval.addr).scale = (yyvsp[(7) - (8)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 107:
-
-/* Line 1806 of yacc.c */
-#line 559 "a.y"
+#line 557 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (1)].gen);
+ (yyval.addr) = (yyvsp[(1) - (1)].addr);
}
break;
case 108:
-
-/* Line 1806 of yacc.c */
-#line 563 "a.y"
+#line 561 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (6)].gen);
- (yyval.gen).index = (yyvsp[(3) - (6)].lval);
- (yyval.gen).scale = (yyvsp[(5) - (6)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = (yyvsp[(1) - (6)].addr);
+ (yyval.addr).index = (yyvsp[(3) - (6)].lval);
+ (yyval.addr).scale = (yyvsp[(5) - (6)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 109:
-
-/* Line 1806 of yacc.c */
-#line 572 "a.y"
+#line 570 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(4) - (5)].lval);
- (yyval.gen).sym = (yyvsp[(1) - (5)].sym);
- (yyval.gen).offset = (yyvsp[(2) - (5)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(4) - (5)].lval);
+ (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
+ (yyval.addr).offset = (yyvsp[(2) - (5)].lval);
}
break;
case 110:
-
-/* Line 1806 of yacc.c */
-#line 579 "a.y"
+#line 577 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_STATIC;
- (yyval.gen).sym = (yyvsp[(1) - (7)].sym);
- (yyval.gen).offset = (yyvsp[(4) - (7)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_STATIC;
+ (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
+ (yyval.addr).offset = (yyvsp[(4) - (7)].lval);
}
break;
case 111:
-
-/* Line 1806 of yacc.c */
-#line 587 "a.y"
+#line 585 "a.y"
{
(yyval.lval) = 0;
}
break;
case 112:
-
-/* Line 1806 of yacc.c */
-#line 591 "a.y"
+#line 589 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 113:
-
-/* Line 1806 of yacc.c */
-#line 595 "a.y"
+#line 593 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 115:
-
-/* Line 1806 of yacc.c */
-#line 602 "a.y"
+#line 600 "a.y"
{
(yyval.lval) = D_AUTO;
}
break;
case 118:
-
-/* Line 1806 of yacc.c */
-#line 610 "a.y"
+#line 608 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
}
break;
case 119:
-
-/* Line 1806 of yacc.c */
-#line 614 "a.y"
+#line 612 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 120:
-
-/* Line 1806 of yacc.c */
-#line 618 "a.y"
+#line 616 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 121:
-
-/* Line 1806 of yacc.c */
-#line 622 "a.y"
+#line 620 "a.y"
{
(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
}
break;
case 122:
-
-/* Line 1806 of yacc.c */
-#line 626 "a.y"
+#line 624 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (3)].lval);
}
break;
case 123:
-
-/* Line 1806 of yacc.c */
-#line 632 "a.y"
+#line 630 "a.y"
{
(yyval.lval) = ((yyvsp[(1) - (1)].lval) & 0xffffffffLL) +
((vlong)ArgsSizeUnknown << 32);
@@ -2734,9 +2489,7 @@ yyreduce:
break;
case 124:
-
-/* Line 1806 of yacc.c */
-#line 637 "a.y"
+#line 635 "a.y"
{
(yyval.lval) = (-(yyvsp[(2) - (2)].lval) & 0xffffffffLL) +
((vlong)ArgsSizeUnknown << 32);
@@ -2744,9 +2497,7 @@ yyreduce:
break;
case 125:
-
-/* Line 1806 of yacc.c */
-#line 642 "a.y"
+#line 640 "a.y"
{
(yyval.lval) = ((yyvsp[(1) - (3)].lval) & 0xffffffffLL) +
(((yyvsp[(3) - (3)].lval) & 0xffffLL) << 32);
@@ -2754,9 +2505,7 @@ yyreduce:
break;
case 126:
-
-/* Line 1806 of yacc.c */
-#line 647 "a.y"
+#line 645 "a.y"
{
(yyval.lval) = (-(yyvsp[(2) - (4)].lval) & 0xffffffffLL) +
(((yyvsp[(4) - (4)].lval) & 0xffffLL) << 32);
@@ -2764,112 +2513,80 @@ yyreduce:
break;
case 128:
-
-/* Line 1806 of yacc.c */
-#line 655 "a.y"
+#line 653 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
}
break;
case 129:
-
-/* Line 1806 of yacc.c */
-#line 659 "a.y"
+#line 657 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
}
break;
case 130:
-
-/* Line 1806 of yacc.c */
-#line 663 "a.y"
+#line 661 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
}
break;
case 131:
-
-/* Line 1806 of yacc.c */
-#line 667 "a.y"
+#line 665 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
}
break;
case 132:
-
-/* Line 1806 of yacc.c */
-#line 671 "a.y"
+#line 669 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
}
break;
case 133:
-
-/* Line 1806 of yacc.c */
-#line 675 "a.y"
+#line 673 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
}
break;
case 134:
-
-/* Line 1806 of yacc.c */
-#line 679 "a.y"
+#line 677 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
}
break;
case 135:
-
-/* Line 1806 of yacc.c */
-#line 683 "a.y"
+#line 681 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
}
break;
case 136:
-
-/* Line 1806 of yacc.c */
-#line 687 "a.y"
+#line 685 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
}
break;
case 137:
-
-/* Line 1806 of yacc.c */
-#line 691 "a.y"
+#line 689 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
}
break;
-
-/* Line 1806 of yacc.c */
-#line 2860 "y.tab.c"
+/* Line 1267 of yacc.c. */
+#line 2588 "y.tab.c"
default: break;
}
- /* User semantic actions sometimes alter yychar, and that requires
- that yytoken be updated with the new translation. We take the
- approach of translating immediately before every use of yytoken.
- One alternative is translating here after every semantic action,
- but that translation would be missed if the semantic action invokes
- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
- incorrect destructor might then be invoked immediately. In the
- case of YYERROR or YYBACKUP, subsequent parser actions might lead
- to an incorrect destructor call or verbose syntax error message
- before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@@ -2878,6 +2595,7 @@ yyreduce:
*++yyvsp = yyval;
+
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
@@ -2897,10 +2615,6 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -2908,36 +2622,37 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
- yyssp, yytoken)
{
- char const *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = YYSYNTAX_ERROR;
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == 1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
- if (!yymsg)
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = 2;
- }
- else
- {
- yysyntax_error_status = YYSYNTAX_ERROR;
- yymsgp = yymsg;
- }
- }
- yyerror (yymsgp);
- if (yysyntax_error_status == 2)
- goto yyexhaustedlab;
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
}
-# undef YYSYNTAX_ERROR
#endif
}
@@ -2945,7 +2660,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
@@ -2962,7 +2677,7 @@ yyerrlab:
}
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
@@ -2996,7 +2711,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
- if (!yypact_value_is_default (yyn))
+ if (yyn != YYPACT_NINF)
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -3019,6 +2734,9 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
*++yyvsp = yylval;
@@ -3043,7 +2761,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -3054,14 +2772,9 @@ yyexhaustedlab:
#endif
yyreturn:
- if (yychar != YYEMPTY)
- {
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = YYTRANSLATE (yychar);
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- }
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
diff --git a/src/cmd/6a/y.tab.h b/src/cmd/6a/y.tab.h
index bba6081dc..e0eb5e12c 100644
--- a/src/cmd/6a/y.tab.h
+++ b/src/cmd/6a/y.tab.h
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison interface for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -116,28 +118,22 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c */
#line 38 "a.y"
-
+{
Sym *sym;
vlong lval;
double dval;
char sval[8];
- Gen gen;
- Gen2 gen2;
-
-
-
-/* Line 2068 of yacc.c */
-#line 135 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+ Addr addr;
+ Addr2 addr2;
+}
+/* Line 1529 of yacc.c. */
+#line 132 "y.tab.h"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
-
diff --git a/src/cmd/6c/gc.h b/src/cmd/6c/gc.h
index c466a3afe..a196e55a8 100644
--- a/src/cmd/6c/gc.h
+++ b/src/cmd/6c/gc.h
@@ -46,11 +46,8 @@
#define SZ_DOUBLE 8
#define FNX 100
-typedef struct Adr Adr;
-typedef struct Prog Prog;
typedef struct Case Case;
typedef struct C1 C1;
-typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
typedef struct Renv Renv;
@@ -64,29 +61,9 @@ EXTERN struct
short ptr;
} idx;
-struct Adr
-{
- vlong offset;
- double dval;
- char sval[NSNAME];
-
- Sym* sym;
- uchar type;
- uchar index;
- uchar etype;
- uchar scale; /* doubles as width in DATA op */
-};
-#define A ((Adr*)0)
-
#define INDEXED 9
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* link;
- int32 lineno;
- short as;
-};
+
+#define A ((Addr*)0)
#define P ((Prog*)0)
struct Case
@@ -105,14 +82,6 @@ struct C1
int32 label;
};
-struct Var
-{
- vlong offset;
- Sym* sym;
- char name;
- char etype;
-};
-
struct Reg
{
int32 pc;
@@ -171,7 +140,6 @@ EXTERN Node vconstnode;
EXTERN int32 continpc;
EXTERN int32 curarg;
EXTERN int32 cursafe;
-EXTERN Prog* firstp;
EXTERN Prog* lastp;
EXTERN int32 maxargsafe;
EXTERN int mnstring;
@@ -226,7 +194,6 @@ EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
-EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
@@ -282,7 +249,7 @@ void regaalloc1(Node*, Node*);
void regaalloc(Node*, Node*);
void regind(Node*, Node*);
void gprep(Node*, Node*);
-void naddr(Node*, Adr*);
+void naddr(Node*, Addr*);
void gcmp(int, Node*, vlong);
void gmove(Node*, Node*);
void gins(int a, Node*, Node*);
@@ -310,19 +277,11 @@ void nullwarn(Node*, Node*);
void sextern(Sym*, Node*, int32, int32);
void gextern(Sym*, Node*, int32, int32);
void outcode(void);
-void ieeedtod(Ieee*, double);
/*
* list
*/
void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Rconv(Fmt*);
-int Xconv(Fmt*);
-int Bconv(Fmt*);
/*
* reg.c
@@ -331,7 +290,7 @@ Reg* rega(void);
int rcmp(const void*, const void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
-Bits mkvar(Reg*, Adr*);
+Bits mkvar(Reg*, Addr*);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, int32);
void synch(Reg*, Bits);
@@ -339,7 +298,7 @@ uint32 allreg(uint32, Rgn*);
void paint1(Reg*, int);
uint32 paint2(Reg*, int);
void paint3(Reg*, int, int32, int);
-void addreg(Adr*, int);
+void addreg(Addr*, int);
/*
* peep.c
@@ -348,17 +307,17 @@ void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
-int regtyp(Adr*);
-int anyvar(Adr*);
+int regtyp(Addr*);
+int anyvar(Addr*);
int subprop(Reg*);
int copyprop(Reg*);
-int copy1(Adr*, Adr*, Reg*, int);
-int copyu(Prog*, Adr*, Adr*);
+int copy1(Addr*, Addr*, Reg*, int);
+int copyu(Prog*, Addr*, Addr*);
-int copyas(Adr*, Adr*);
-int copyau(Adr*, Adr*);
-int copysub(Adr*, Adr*, Adr*, int);
-int copysub1(Prog*, Adr*, Adr*, int);
+int copyas(Addr*, Addr*);
+int copyau(Addr*, Addr*);
+int copysub(Addr*, Addr*, Addr*, int);
+int copysub1(Prog*, Addr*, Addr*, int);
int32 RtoB(int);
int32 FtoB(int);
@@ -396,14 +355,6 @@ void mulgen(Type*, Node*, Node*);
void genmuladd(Node*, Node*, int, Node*);
void shiftit(Type*, Node*, Node*);
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Adr*
-#pragma varargck type "lD" Adr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-
#define D_X7 (D_X0+7)
void fgopcode(int, Node*, Node*, int, int);
diff --git a/src/cmd/6c/list.c b/src/cmd/6c/list.c
index b5a60ac9a..28f5b8df7 100644
--- a/src/cmd/6c/list.c
+++ b/src/cmd/6c/list.c
@@ -34,358 +34,5 @@
void
listinit(void)
{
-
- fmtinstall('A', Aconv);
- fmtinstall('B', Bconv);
- fmtinstall('P', Pconv);
- fmtinstall('S', Sconv);
- fmtinstall('D', Dconv);
- fmtinstall('R', Rconv);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == S) {
- sprint(ss, "$%lld", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- switch(p->as) {
- case ADATA:
- sprint(str, "(%L) %A %D/%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
-
- case ATEXT:
- if(p->from.scale) {
- sprint(str, "(%L) %A %D,%d,%lD",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- sprint(str, "(%L) %A %D,%lD",
- p->lineno, p->as, &p->from, &p->to);
- break;
-
- default:
- sprint(str, "(%L) %A %D,%D",
- p->lineno, p->as, &p->from, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Adr *a;
- int i;
-
- a = va_arg(fp->args, Adr*);
- i = a->type;
-
- if(fp->flags & FmtLong) {
- if(i == D_CONST)
- sprint(str, "$%lld-%lld", a->offset&0xffffffffLL, a->offset>>32);
- else {
- // ATEXT dst is not constant
- sprint(str, "!!%D", a);
- }
- goto brk;
- }
-
- if(i >= D_INDIR) {
- if(a->offset)
- sprint(str, "%lld(%R)", a->offset, i-D_INDIR);
- else
- sprint(str, "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
- default:
- if(a->offset)
- sprint(str, "$%lld,%R", a->offset, i);
- else
- sprint(str, "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- sprint(str, "%lld", a->offset);
- break;
-
- case D_EXTERN:
- sprint(str, "%s+%lld(SB)", a->sym->name, a->offset);
- break;
-
- case D_STATIC:
- sprint(str, "%s<>+%lld(SB)", a->sym->name, a->offset);
- break;
-
- case D_AUTO:
- if(a->sym)
- sprint(str, "%s+%lld(SP)", a->sym->name, a->offset);
- else
- sprint(str, "%lld(SP)", a->offset);
- break;
-
- case D_PARAM:
- if(a->sym)
- sprint(str, "%s+%lld(FP)", a->sym->name, a->offset);
- else
- sprint(str, "%lld(FP)", a->offset);
- break;
-
- case D_CONST:
- sprint(str, "$%lld", a->offset);
- break;
-
- case D_FCONST:
- sprint(str, "$(%.17e)", a->dval);
- break;
-
- case D_SCONST:
- sprint(str, "$\"%S\"", a->sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- sprint(str, "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
- }
-conv:
- return fmtstrcpy(fp, str);
-}
-
-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",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_AL && r <= D_NONE)
- sprint(str, "%s", regstr[r-D_AL]);
- else
- sprint(str, "gok(%d)", r);
-
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(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);
+ listinit6();
}
diff --git a/src/cmd/6c/peep.c b/src/cmd/6c/peep.c
index 0a3bd84bc..a11067c84 100644
--- a/src/cmd/6c/peep.c
+++ b/src/cmd/6c/peep.c
@@ -276,7 +276,7 @@ uniqs(Reg *r)
}
int
-regtyp(Adr *a)
+regtyp(Addr *a)
{
int t;
@@ -306,7 +306,7 @@ int
subprop(Reg *r0)
{
Prog *p;
- Adr *v1, *v2;
+ Addr *v1, *v2;
Reg *r;
int t;
@@ -445,7 +445,7 @@ int
copyprop(Reg *r0)
{
Prog *p;
- Adr *v1, *v2;
+ Addr *v1, *v2;
Reg *r;
p = r0->prog;
@@ -459,7 +459,7 @@ copyprop(Reg *r0)
}
int
-copy1(Adr *v1, Adr *v2, Reg *r, int f)
+copy1(Addr *v1, Addr *v2, Reg *r, int f)
{
int t;
Prog *p;
@@ -544,7 +544,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f)
* 0 otherwise (not touched)
*/
int
-copyu(Prog *p, Adr *v, Adr *s)
+copyu(Prog *p, Addr *v, Addr *s)
{
switch(p->as) {
@@ -835,7 +835,7 @@ copyu(Prog *p, Adr *v, Adr *s)
* semantics
*/
int
-copyas(Adr *a, Adr *v)
+copyas(Addr *a, Addr *v)
{
if(a->type != v->type)
return 0;
@@ -851,7 +851,7 @@ copyas(Adr *a, Adr *v)
* either direct or indirect
*/
int
-copyau(Adr *a, Adr *v)
+copyau(Addr *a, Addr *v)
{
if(copyas(a, v))
@@ -870,7 +870,7 @@ copyau(Adr *a, Adr *v)
* return failure to substitute
*/
int
-copysub(Adr *a, Adr *v, Adr *s, int f)
+copysub(Addr *a, Addr *v, Addr *s, int f)
{
int t;
diff --git a/src/cmd/6c/reg.c b/src/cmd/6c/reg.c
index edd93a0a0..348d747b7 100644
--- a/src/cmd/6c/reg.c
+++ b/src/cmd/6c/reg.c
@@ -663,8 +663,10 @@ brk:
r1 = 0; /* set */
for(r = firstr; r != R; r = r->link) {
p = r->prog;
- if(p->to.type == D_BRANCH)
+ if(p->to.type == D_BRANCH) {
p->to.offset = r->s2->pc;
+ p->to.u.branch = r->s2->prog;
+ }
r1 = r;
}
@@ -691,7 +693,7 @@ void
addmove(Reg *r, int bn, int rn, int f)
{
Prog *p, *p1;
- Adr *a;
+ Addr *a;
Var *v;
p1 = alloc(sizeof(*p1));
@@ -715,7 +717,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1->as = AMOVB;
if(v->etype == TSHORT || v->etype == TUSHORT)
p1->as = AMOVW;
- if(v->etype == TVLONG || v->etype == TUVLONG || v->etype == TIND)
+ if(v->etype == TVLONG || v->etype == TUVLONG || (v->etype == TIND && ewidth[TIND] == 8))
p1->as = AMOVQ;
if(v->etype == TFLOAT)
p1->as = AMOVSS;
@@ -759,13 +761,13 @@ doregbits(int r)
}
Bits
-mkvar(Reg *r, Adr *a)
+mkvar(Reg *r, Addr *a)
{
Var *v;
int i, t, n, et, z;
int32 o;
Bits bit;
- Sym *s;
+ LSym *s;
/*
* mark registers used
@@ -792,7 +794,7 @@ mkvar(Reg *r, Adr *a)
break;
}
s = a->sym;
- if(s == S)
+ if(s == nil)
goto none;
if(s->name[0] == '.')
goto none;
@@ -1181,7 +1183,7 @@ uint32
regset(Reg *r, uint32 bb)
{
uint32 b, set;
- Adr v;
+ Addr v;
int c;
set = 0;
@@ -1202,7 +1204,7 @@ uint32
reguse(Reg *r, uint32 bb)
{
uint32 b, set;
- Adr v;
+ Addr v;
int c;
set = 0;
@@ -1349,7 +1351,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
}
void
-addreg(Adr *a, int rn)
+addreg(Addr *a, int rn)
{
a->sym = 0;
@@ -1371,6 +1373,8 @@ BtoR(int32 b)
{
b &= 0xffffL;
+ if(nacl)
+ b &= ~((1<<(D_BP-D_AX)) | (1<<(D_R15-D_AX)));
if(b == 0)
return 0;
return bitno(b) + D_AX;
@@ -1459,10 +1463,11 @@ fixjmp(Reg *firstr)
for(r=firstr; r; r=r->link) {
p = r->prog;
if(debug['R'] && debug['v'])
- print("%04d %P\n", r->pc, p);
+ print("%04d %P\n", (int)r->pc, p);
if(p->as != ACALL && p->to.type == D_BRANCH && r->s2 && r->s2->prog->as == AJMP) {
r->s2 = chasejmp(r->s2, &jmploop);
p->to.offset = r->s2->pc;
+ p->to.u.branch = r->s2->prog;
if(debug['R'] && debug['v'])
print("->%P\n", p);
}
@@ -1483,7 +1488,7 @@ fixjmp(Reg *firstr)
// Let it stay.
} else {
if(debug['R'] && debug['v'])
- print("del %04d %P\n", r->pc, p);
+ print("del %04d %P\n", (int)r->pc, p);
p->as = ANOP;
}
}
@@ -1496,7 +1501,7 @@ fixjmp(Reg *firstr)
p = r->prog;
if(p->as == AJMP && p->to.type == D_BRANCH && r->s2 == r->link) {
if(debug['R'] && debug['v'])
- print("del %04d %P\n", r->pc, p);
+ print("del %04d %P\n", (int)r->pc, p);
p->as = ANOP;
}
}
@@ -1517,7 +1522,7 @@ fixjmp(Reg *firstr)
if(debug['R'] && debug['v']) {
print("\n");
for(r=firstr; r; r=r->link)
- print("%04d %P\n", r->pc, r->prog);
+ print("%04d %P\n", (int)r->pc, r->prog);
print("\n");
}
}
diff --git a/src/cmd/6c/sgen.c b/src/cmd/6c/sgen.c
index 744a60222..ba1c1f652 100644
--- a/src/cmd/6c/sgen.c
+++ b/src/cmd/6c/sgen.c
@@ -207,7 +207,7 @@ xcom(Node *n)
n->addable = 8;
break;
}
- if(n->addable == 8 && !side(n)) {
+ if(n->addable == 8 && !side(n) && !nacl) {
indx(n);
l = new1(OINDEX, idx.basetree, idx.regtree);
l->scale = idx.scale;
diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c
index 2496da477..d7713648d 100644
--- a/src/cmd/6c/swt.c
+++ b/src/cmd/6c/swt.c
@@ -164,7 +164,7 @@ outstring(char *s, int32 n)
p->from.offset += nstring - NSNAME;
p->from.scale = NSNAME;
p->to.type = D_SCONST;
- memmove(p->to.sval, string, NSNAME);
+ memmove(p->to.u.sval, string, NSNAME);
mnstring = 0;
}
n--;
@@ -185,7 +185,7 @@ sextern(Sym *s, Node *a, int32 o, int32 w)
p->from.offset += o+e;
p->from.scale = lw;
p->to.type = D_SCONST;
- memmove(p->to.sval, a->cstring+e, lw);
+ memmove(p->to.u.sval, a->cstring+e, lw);
}
}
@@ -215,30 +215,12 @@ gextern(Sym *s, Node *a, int32 o, int32 w)
}
}
-void zname(Biobuf*, Sym*, int);
-void zaddr(Biobuf*, Adr*, int);
-void outhist(Biobuf*);
-
void
outcode(void)
{
- struct { Sym *sym; short type; } h[NSYM];
- Prog *p;
- Sym *s;
- int f, sf, st, t, sym;
+ int f;
Biobuf b;
- if(debug['S']) {
- for(p = firstp; p != P; p = p->link)
- if(p->as != ADATA && p->as != AGLOBL)
- pc--;
- for(p = firstp; p != P; p = p->link) {
- print("%P\n", p);
- if(p->as != ADATA && p->as != AGLOBL)
- pc++;
- }
- }
-
f = open(outfile, OWRITE);
if(f < 0) {
diag(Z, "cannot open %s", outfile);
@@ -246,7 +228,7 @@ outcode(void)
}
Binit(&b, f, OWRITE);
- Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
+ Bprint(&b, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&b, "\n");
Bprint(&b, "$$ // exports\n\n");
@@ -257,261 +239,12 @@ outcode(void)
}
Bprint(&b, "!\n");
- outhist(&b);
- for(sym=0; sym<NSYM; sym++) {
- h[sym].sym = S;
- h[sym].type = 0;
- }
- sym = 1;
- for(p = firstp; p != P; p = p->link) {
- jackpot:
- sf = 0;
- s = p->from.sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = p->from.type;
- if(t == D_ADDR)
- t = p->from.index;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- s->sym = sym;
- zname(&b, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = p->to.sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = p->to.type;
- if(t == D_ADDR)
- t = p->to.index;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- s->sym = sym;
- zname(&b, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- BPUTLE2(&b, p->as);
- BPUTLE4(&b, p->lineno);
- zaddr(&b, &p->from, sf);
- zaddr(&b, &p->to, st);
- }
+ writeobj(ctxt, &b);
Bterm(&b);
close(f);
- firstp = P;
lastp = P;
}
-void
-outhist(Biobuf *b)
-{
- Hist *h;
- char *p, *q, *op, c;
- Prog pg;
- int n;
- char *tofree;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
- pg = zprog;
- pg.as = AHISTORY;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p != nil && goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- op = 0;
- if(systemtype(Windows) && p && p[1] == ':'){
- c = p[2];
- } else if(p && p[0] != c && h->offset == 0 && pathname){
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname;
- c = p[2];
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = utfrune(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- BPUTLE2(b, ANAME);
- BPUTC(b, D_FILE);
- BPUTC(b, 1);
- BPUTC(b, '<');
- Bwrite(b, p, n);
- BPUTC(b, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- pg.lineno = h->line;
- pg.to.type = zprog.to.type;
- pg.to.offset = h->offset;
- if(h->offset)
- pg.to.type = D_CONST;
-
- BPUTLE2(b, pg.as);
- BPUTLE4(b, pg.lineno);
- zaddr(b, &pg.from, 0);
- zaddr(b, &pg.to, 0);
-
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- char *n;
- uint32 sig;
-
- if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
- sig = sign(s);
- BPUTLE2(b, ASIGNAME);
- BPUTLE4(b, sig);
- s->sig = SIGDONE;
- }
- else{
- BPUTLE2(b, ANAME); /* as */
- }
- BPUTC(b, t); /* type */
- BPUTC(b, s->sym); /* sym */
- n = s->name;
- while(*n) {
- BPUTC(b, *n);
- n++;
- }
- BPUTC(b, 0);
-}
-
-void
-zaddr(Biobuf *b, Adr *a, int s)
-{
- int32 l;
- int i, t;
- char *n;
- Ieee e;
-
- t = 0;
- if(a->index != D_NONE || a->scale != 0)
- t |= T_INDEX;
- if(s != 0)
- t |= T_SYM;
-
- switch(a->type) {
- default:
- t |= T_TYPE;
- case D_NONE:
- if(a->offset != 0) {
- t |= T_OFFSET;
- l = a->offset;
- if((vlong)l != a->offset)
- t |= T_64;
- }
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- }
- BPUTC(b, t);
-
- if(t & T_INDEX) { /* implies index, scale */
- BPUTC(b, a->index);
- BPUTC(b, a->scale);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- BPUTLE4(b, l);
- if(t & T_64) {
- l = a->offset>>32;
- BPUTLE4(b, l);
- }
- }
- if(t & T_SYM) /* implies sym */
- BPUTC(b, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->dval);
- l = e.l;
- BPUTLE4(b, l);
- l = e.h;
- BPUTLE4(b, l);
- return;
- }
- if(t & T_SCONST) {
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(b, *n);
- n++;
- }
- return;
- }
- if(t & T_TYPE)
- BPUTC(b, a->type);
-}
-
int32
align(int32 i, Type *t, int op, int32 *maxalign)
{
@@ -559,6 +292,21 @@ align(int32 i, Type *t, int op, int32 *maxalign)
break;
case Aarg1: /* initial align of parameter */
+ if(ewidth[TIND] == 4) {
+ if(typesu[t->etype]) {
+ for(v = t->link; v != T; v = v->down)
+ o = align(o, v, Aarg1, maxalign);
+ goto out;
+ }
+ w = ewidth[t->etype];
+ if(typev[t->etype] || t->etype == TDOUBLE)
+ w = 8;
+ else if(w <= 0 || w >= 4)
+ w = 4;
+ else
+ w = 1;
+ break;
+ }
w = ewidth[t->etype];
if(w <= 0 || w >= SZ_VLONG) {
w = SZ_VLONG;
@@ -569,6 +317,10 @@ align(int32 i, Type *t, int op, int32 *maxalign)
case Aarg2: /* width of a parameter */
o += t->width;
+ if(ewidth[TIND] == 4) {
+ o = align(o, t, Aarg1, maxalign);
+ goto out;
+ }
w = t->width;
if(w > SZ_VLONG)
w = SZ_VLONG;
@@ -582,6 +334,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
o = xround(o, w);
if(maxalign && *maxalign < w)
*maxalign = w;
+out:
if(debug['A'])
print("align %s %d %T = %d\n", bnames[op], i, t, o);
return o;
diff --git a/src/cmd/6c/txt.c b/src/cmd/6c/txt.c
index 6f5d42da5..4d07436c3 100644
--- a/src/cmd/6c/txt.c
+++ b/src/cmd/6c/txt.c
@@ -30,15 +30,27 @@
#include "gc.h"
+int thechar = '6';
+char *thestring = "amd64";
+
+LinkArch *thelinkarch = &linkamd64;
+
+void
+linkarchinit(void)
+{
+ if(strcmp(getgoarch(), "amd64p32") == 0)
+ thelinkarch = &linkamd64p32;
+}
+
void
ginit(void)
{
int i;
Type *t;
- thechar = '6';
- thestring = "amd64";
- dodefine("_64BIT");
+ dodefine("_64BITREG");
+ if(ewidth[TIND] == 8)
+ dodefine("_64BIT");
listinit();
nstring = 0;
mnstring = 0;
@@ -47,7 +59,6 @@ ginit(void)
breakpc = -1;
continpc = -1;
cases = C;
- firstp = P;
lastp = P;
tfield = types[TINT];
@@ -129,6 +140,10 @@ ginit(void)
if(i >= D_X0 && i <= D_X7)
reg[i] = 0;
}
+ if(nacl) {
+ reg[D_BP] = 1;
+ reg[D_R15] = 1;
+ }
}
void
@@ -138,6 +153,10 @@ gclean(void)
Sym *s;
reg[D_SP]--;
+ if(nacl) {
+ reg[D_BP]--;
+ reg[D_R15]--;
+ }
for(i=D_AX; i<=D_R15; i++)
if(reg[i])
diag(Z, "reg %R left allocated", i);
@@ -168,17 +187,18 @@ gclean(void)
void
nextpc(void)
{
+ Plist *pl;
p = alloc(sizeof(*p));
*p = zprog;
p->lineno = nearln;
+ p->pc = pc;
pc++;
- if(firstp == P) {
- firstp = p;
- lastp = p;
- return;
- }
- lastp->link = p;
+ if(lastp == nil) {
+ pl = linknewplist(ctxt);
+ pl->firstpc = p;
+ } else
+ lastp->link = p;
lastp = p;
}
@@ -441,7 +461,7 @@ regaalloc1(Node *n, Node *nn)
return;
}
nodreg(n, nn, REGARG);
- reg[REGARG]++;
+ reg[(uchar)REGARG]++;
curarg = align(curarg, nn->type, Aarg1, nil);
curarg = align(curarg, nn->type, Aarg2, nil);
maxargsafe = maxround(maxargsafe, cursafe+curarg);
@@ -474,7 +494,7 @@ regind(Node *n, Node *nn)
}
void
-naddr(Node *n, Adr *a)
+naddr(Node *n, Addr *a)
{
int32 v;
@@ -489,11 +509,11 @@ naddr(Node *n, Adr *a)
case OREGISTER:
a->type = n->reg;
- a->sym = S;
+ a->sym = nil;
break;
case OEXREG:
- a->type = D_INDIR + D_GS;
+ a->type = D_INDIR + D_TLS;
a->offset = n->reg - 1;
break;
@@ -534,14 +554,14 @@ naddr(Node *n, Adr *a)
case OINDREG:
a->type = n->reg+D_INDIR;
- a->sym = S;
+ a->sym = nil;
a->offset = n->xoffset;
break;
case ONAME:
a->etype = n->etype;
a->type = D_STATIC;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
a->offset = n->xoffset;
if(n->class == CSTATIC)
break;
@@ -562,12 +582,12 @@ naddr(Node *n, Adr *a)
case OCONST:
if(typefd[n->type->etype]) {
a->type = D_FCONST;
- a->dval = n->fconst;
+ a->u.dval = n->fconst;
break;
}
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
- if(typev[n->type->etype] || n->type->etype == TIND)
+ if(typev[n->type->etype] || (n->type->etype == TIND && ewidth[TIND] == 8))
a->offset = n->vconst;
else
a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
@@ -630,6 +650,12 @@ gmove(Node *f, Node *t)
ft = f->type->etype;
tt = t->type->etype;
+ if(ewidth[TIND] == 4) {
+ if(ft == TIND)
+ ft = TUINT;
+ if(tt == TIND)
+ tt = TUINT;
+ }
t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
if(debug['M'])
print("gop: %O %O[%s],%O[%s]\n", OAS,
@@ -721,6 +747,8 @@ gmove(Node *f, Node *t)
goto ld;
case TIND:
a = AMOVQ;
+ if(ewidth[TIND] == 4)
+ a = AMOVL;
ld:
regalloc(&nod, f, t);
@@ -1226,6 +1254,8 @@ gopcode(int o, Type *ty, Node *f, Node *t)
et = TLONG;
if(ty != T)
et = ty->etype;
+ if(et == TIND && ewidth[TIND] == 4)
+ et = TUINT;
if(debug['M']) {
if(f != Z && f->type != T)
print("gop: %O %O[%s],", o, f->op, tnames[et]);
@@ -1487,9 +1517,10 @@ gbranch(int o)
void
patch(Prog *op, int32 pc)
{
-
op->to.offset = pc;
op->to.type = D_BRANCH;
+ op->to.u.branch = nil;
+ op->pcond = nil;
}
void
@@ -1499,7 +1530,7 @@ gpseudo(int a, Sym *s, Node *n)
nextpc();
p->as = a;
p->from.type = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
switch(a) {
case ATEXT:
@@ -1561,7 +1592,7 @@ exreg(Type *t)
if(exregoffset >= 64)
return 0;
o = exregoffset;
- exregoffset += 8;
+ exregoffset += ewidth[TIND];
return o+1; // +1 to avoid 0 == failure; naddr's case OEXREG will subtract 1.
}
return 0;
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index ada2baa81..4dd505b08 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -247,6 +247,7 @@ cgen(Node *n, Node *res)
case OOR:
case OXOR:
case OADD:
+ case OADDPTR:
case OMUL:
a = optoas(n->op, nl->type);
if(a == AIMULB) {
@@ -813,6 +814,7 @@ agen(Node *n, Node *res)
// The generated code is just going to panic, so it need not
// be terribly efficient. See issue 3670.
tempname(&n1, n->type);
+ gvardef(&n1);
clearfat(&n1);
regalloc(&n2, types[tptr], res);
gins(ALEAQ, &n1, &n2);
@@ -1060,6 +1062,12 @@ bgen(Node *n, int true, int likely, Prog *to)
}
nr = N;
+ while(n->op == OCONVNOP) {
+ n = n->left;
+ if(n->ninit != nil)
+ genlist(n->ninit);
+ }
+
switch(n->op) {
default:
def:
@@ -1337,6 +1345,8 @@ sgen(Node *n, Node *ns, int64 w)
{
Node nodl, nodr, nodsi, noddi, cx, oldcx, tmp;
vlong c, q, odst, osrc;
+ NodeList *l;
+ Prog *p;
if(debug['g']) {
print("\nsgen w=%lld\n", w);
@@ -1349,6 +1359,13 @@ sgen(Node *n, Node *ns, int64 w)
if(w < 0)
fatal("sgen copy %lld", w);
+
+ // If copying .args, that's all the results, so record definition sites
+ // for them for the liveness analysis.
+ if(ns->op == ONAME && strcmp(ns->sym->name, ".args") == 0)
+ for(l = curfn->dcl; l != nil; l = l->next)
+ if(l->n->class == PPARAMOUT)
+ gvardef(l->n);
// Avoid taking the address for simple enough types.
if(componentgen(n, ns))
@@ -1380,11 +1397,16 @@ sgen(Node *n, Node *ns, int64 w)
if(n->ullman >= ns->ullman) {
agenr(n, &nodr, N);
+ if(ns->op == ONAME)
+ gvardef(ns);
agenr(ns, &nodl, N);
} else {
+ if(ns->op == ONAME)
+ gvardef(ns);
agenr(ns, &nodl, N);
agenr(n, &nodr, N);
}
+
nodreg(&noddi, types[tptr], D_DI);
nodreg(&nodsi, types[tptr], D_SI);
gmove(&nodl, &noddi);
@@ -1403,23 +1425,23 @@ sgen(Node *n, Node *ns, int64 w)
// reverse direction
gins(ASTD, N, N); // set direction flag
if(c > 0) {
- gconreg(AADDQ, w-1, D_SI);
- gconreg(AADDQ, w-1, D_DI);
+ gconreg(addptr, w-1, D_SI);
+ gconreg(addptr, w-1, D_DI);
- gconreg(AMOVQ, c, D_CX);
+ gconreg(movptr, c, D_CX);
gins(AREP, N, N); // repeat
gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)-
}
if(q > 0) {
if(c > 0) {
- gconreg(AADDQ, -7, D_SI);
- gconreg(AADDQ, -7, D_DI);
+ gconreg(addptr, -7, D_SI);
+ gconreg(addptr, -7, D_DI);
} else {
- gconreg(AADDQ, w-8, D_SI);
- gconreg(AADDQ, w-8, D_DI);
+ gconreg(addptr, w-8, D_SI);
+ gconreg(addptr, w-8, D_DI);
}
- gconreg(AMOVQ, q, D_CX);
+ gconreg(movptr, q, D_CX);
gins(AREP, N, N); // repeat
gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)-
}
@@ -1427,23 +1449,48 @@ sgen(Node *n, Node *ns, int64 w)
gins(ACLD, N, N);
} else {
// normal direction
- if(q >= 4) {
- gconreg(AMOVQ, q, D_CX);
+ if(q > 128 || (nacl && q >= 4)) {
+ gconreg(movptr, q, D_CX);
gins(AREP, N, N); // repeat
gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
+ } else if (q >= 4) {
+ p = gins(ADUFFCOPY, N, N);
+ p->to.type = D_ADDR;
+ p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
+ // 14 and 128 = magic constants: see ../../pkg/runtime/asm_amd64.s
+ p->to.offset = 14*(128-q);
} else
while(q > 0) {
gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
q--;
}
-
- if(c >= 4) {
- gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
- c -= 4;
- }
- while(c > 0) {
- gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
- c--;
+ // copy the remaining c bytes
+ if(w < 4 || c <= 1 || (odst < osrc && osrc < odst+w)) {
+ while(c > 0) {
+ gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
+ c--;
+ }
+ } else if(w < 8 || c <= 4) {
+ nodsi.op = OINDREG;
+ noddi.op = OINDREG;
+ nodsi.type = types[TINT32];
+ noddi.type = types[TINT32];
+ if(c > 4) {
+ nodsi.xoffset = 0;
+ noddi.xoffset = 0;
+ gmove(&nodsi, &noddi);
+ }
+ nodsi.xoffset = c-4;
+ noddi.xoffset = c-4;
+ gmove(&nodsi, &noddi);
+ } else {
+ nodsi.op = OINDREG;
+ noddi.op = OINDREG;
+ nodsi.type = types[TINT64];
+ noddi.type = types[TINT64];
+ nodsi.xoffset = c-8;
+ noddi.xoffset = c-8;
+ gmove(&nodsi, &noddi);
}
}
@@ -1513,7 +1560,7 @@ componentgen(Node *nr, Node *nl)
fatal("componentgen: not a TFIELD: %lT", t);
fldcount++;
}
- if(fldcount == 0 || fldcount > 3)
+ if(fldcount == 0 || fldcount > 4)
goto no;
break;
@@ -1538,10 +1585,19 @@ componentgen(Node *nr, Node *nl)
freer = 1;
}
}
+
+ // nl and nr are 'cadable' which basically means they are names (variables) now.
+ // If they are the same variable, don't generate any code, because the
+ // VARDEF we generate will mark the old value as dead incorrectly.
+ // (And also the assignments are useless.)
+ if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
+ goto yes;
switch(nl->type->etype) {
case TARRAY:
// componentgen for arrays.
+ if(nl->op == ONAME)
+ gvardef(nl);
t = nl->type;
if(!isslice(t)) {
nodl.type = t->type;
@@ -1591,6 +1647,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TSTRING:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
@@ -1614,6 +1672,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TINTER:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
@@ -1637,6 +1697,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TSTRUCT:
+ if(nl->op == ONAME)
+ gvardef(nl);
loffset = nodl.xoffset;
roffset = nodr.xoffset;
// funarg structs may not begin at offset zero.
diff --git a/src/cmd/6g/galign.c b/src/cmd/6g/galign.c
index 526c04c06..1d32c5a61 100644
--- a/src/cmd/6g/galign.c
+++ b/src/cmd/6g/galign.c
@@ -8,9 +8,22 @@
int thechar = '6';
char* thestring = "amd64";
+LinkArch* thelinkarch = &linkamd64;
+
+void
+linkarchinit(void)
+{
+ if(strcmp(getgoarch(), "amd64p32") == 0)
+ thelinkarch = &linkamd64p32;
+}
vlong MAXWIDTH = 1LL<<50;
+int addptr = AADDQ;
+int movptr = AMOVQ;
+int leaptr = ALEAQ;
+int cmpptr = ACMPQ;
+
/*
* go declares several platform-specific type aliases:
* int, uint, float, and uintptr
@@ -28,6 +41,19 @@ betypeinit(void)
{
widthptr = 8;
widthint = 8;
+ widthreg = 8;
+ if(strcmp(getgoarch(), "amd64p32") == 0) {
+ widthptr = 4;
+ widthint = 4;
+ addptr = AADDL;
+ movptr = AMOVL;
+ leaptr = ALEAL;
+ cmpptr = ACMPL;
+ typedefs[0].sameas = TINT32;
+ typedefs[1].sameas = TUINT32;
+ typedefs[2].sameas = TUINT32;
+
+ }
zprog.link = P;
zprog.as = AGOK;
@@ -36,5 +62,5 @@ betypeinit(void)
zprog.from.scale = 0;
zprog.to = zprog.from;
- listinit();
+ listinit6();
}
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index 3ef59c788..a5da17d61 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -9,56 +9,25 @@
#include "../gc/go.h"
#include "../6l/6.out.h"
-typedef struct Addr Addr;
-
-struct Addr
-{
- vlong offset;
-
- union {
- double dval;
- vlong vval;
- Prog* branch;
- char sval[NSNAME];
- } u;
-
- Sym* gotype;
- Sym* sym;
- Node* node;
- int64 width;
- uchar type;
- uchar index;
- uchar etype;
- uchar scale; /* doubles as width in DATA op */
-};
-#define A ((Addr*)0)
-
-struct Prog
-{
- short as; // opcode
- uint32 loc; // pc offset in this func
- uint32 lineno; // source line that generated this
- Addr from; // src address
- Addr to; // dst address
- Prog* link; // next instruction in this func
- void* opt; // for optimizer passes
-};
-
#define TEXTFLAG from.scale
EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE];
EXTERN int32 pcloc; // instruction counter
EXTERN Strlit emptystring;
-extern char* anames[];
EXTERN Prog zprog;
EXTERN Node* newproc;
EXTERN Node* deferproc;
EXTERN Node* deferreturn;
EXTERN Node* panicindex;
EXTERN Node* panicslice;
+EXTERN Node* panicdiv;
EXTERN Node* throwreturn;
extern vlong unmappedzero;
+extern int addptr;
+extern int cmpptr;
+extern int movptr;
+extern int leaptr;
/*
* ggen.c
@@ -150,14 +119,6 @@ void datagostring(Strlit*, Addr*);
/*
* list.c
*/
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Yconv(Fmt*);
void listinit(void);
void zaddr(Biobuf*, Addr*, int, int);
-
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index 9fad9f7f1..c385798f2 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -9,59 +9,110 @@
#include "gg.h"
#include "opt.h"
-static Prog* appendp(Prog*, int, int, vlong, int, vlong);
+static Prog *appendpp(Prog*, int, int, vlong, int, vlong);
+static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
void
-defframe(Prog *ptxt, Bvec *bv)
+defframe(Prog *ptxt)
{
- int i, j;
- uint32 frame;
+ uint32 frame, ax;
Prog *p;
+ vlong hi, lo;
+ NodeList *l;
+ Node *n;
// fill in argument size
ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
ptxt->to.offset <<= 32;
- frame = rnd(stksize+maxarg, widthptr);
+ frame = rnd(stksize+maxarg, widthreg);
ptxt->to.offset |= frame;
-
- // insert code to clear pointered part of the frame,
- // so that garbage collector only sees initialized values
+
+ // insert code to zero ambiguously live variables
+ // so that the garbage collector only sees initialized values
// when it looks for pointers.
p = ptxt;
- if(stkzerosize >= 8*widthptr) {
- p = appendp(p, AMOVQ, D_CONST, 0, D_AX, 0);
- p = appendp(p, AMOVQ, D_CONST, stkzerosize/widthptr, D_CX, 0);
- p = appendp(p, ALEAQ, D_SP+D_INDIR, frame-stkzerosize, D_DI, 0);
- p = appendp(p, AREP, D_NONE, 0, D_NONE, 0);
- appendp(p, ASTOSQ, D_NONE, 0, D_NONE, 0);
- } else {
- j = (stkptrsize - stkzerosize)/widthptr * 2;
- for(i=0; i<stkzerosize; i+=widthptr) {
- if(bvget(bv, j) || bvget(bv, j+1))
- p = appendp(p, AMOVQ, D_CONST, 0, D_SP+D_INDIR, frame-stkzerosize+i);
- j += 2;
+ lo = hi = 0;
+ ax = 0;
+ // iterate through declarations - they are sorted in decreasing xoffset order.
+ for(l=curfn->dcl; l != nil; l = l->next) {
+ n = l->n;
+ if(!n->needzero)
+ continue;
+ if(n->class != PAUTO)
+ fatal("needzero class %d", n->class);
+ if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
+ fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
+
+ if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthreg) {
+ // merge with range we already have
+ lo = n->xoffset;
+ continue;
}
+ // zero old range
+ p = zerorange(p, frame, lo, hi, &ax);
+
+ // set new range
+ hi = n->xoffset + n->type->width;
+ lo = n->xoffset;
}
+ // zero final range
+ zerorange(p, frame, lo, hi, &ax);
}
static Prog*
-appendp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
+zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
+{
+ vlong cnt, i;
+
+ cnt = hi - lo;
+ if(cnt == 0)
+ return p;
+ if(*ax == 0) {
+ p = appendpp(p, AMOVQ, D_CONST, 0, D_AX, 0);
+ *ax = 1;
+ }
+ if(cnt % widthreg != 0) {
+ // should only happen with nacl
+ if(cnt % widthptr != 0)
+ fatal("zerorange count not a multiple of widthptr %d", cnt);
+ p = appendpp(p, AMOVL, D_AX, 0, D_SP+D_INDIR, frame+lo);
+ lo += widthptr;
+ cnt -= widthptr;
+ }
+ if(cnt <= 4*widthreg) {
+ for(i = 0; i < cnt; i += widthreg) {
+ p = appendpp(p, AMOVQ, D_AX, 0, D_SP+D_INDIR, frame+lo+i);
+ }
+ } else if(!nacl && (cnt <= 128*widthreg)) {
+ p = appendpp(p, leaptr, D_SP+D_INDIR, frame+lo, D_DI, 0);
+ p = appendpp(p, ADUFFZERO, D_NONE, 0, D_ADDR, 2*(128-cnt/widthreg));
+ p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
+ } else {
+ p = appendpp(p, AMOVQ, D_CONST, cnt/widthreg, D_CX, 0);
+ p = appendpp(p, leaptr, D_SP+D_INDIR, frame+lo, D_DI, 0);
+ p = appendpp(p, AREP, D_NONE, 0, D_NONE, 0);
+ p = appendpp(p, ASTOSQ, D_NONE, 0, D_NONE, 0);
+ }
+ return p;
+}
+
+static Prog*
+appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
{
Prog *q;
-
- q = mal(sizeof(*q));
- clearp(q);
- q->as = as;
- q->lineno = p->lineno;
- q->from.type = ftype;
- q->from.offset = foffset;
- q->to.type = ttype;
- q->to.offset = toffset;
- q->link = p->link;
- p->link = q;
- return q;
+ q = mal(sizeof(*q));
+ clearp(q);
+ q->as = as;
+ q->lineno = p->lineno;
+ q->from.type = ftype;
+ q->from.offset = foffset;
+ q->to.type = ttype;
+ q->to.offset = toffset;
+ q->link = p->link;
+ p->link = q;
+ return q;
}
// Sweep the prog list to mark any used nodes.
@@ -69,13 +120,13 @@ void
markautoused(Prog* p)
{
for (; p; p = p->link) {
- if (p->as == ATYPE)
+ if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
continue;
- if (p->from.type == D_AUTO && p->from.node)
+ if (p->from.node)
p->from.node->used = 1;
- if (p->to.type == D_AUTO && p->to.node)
+ if (p->to.node)
p->to.node->used = 1;
}
}
@@ -91,6 +142,16 @@ fixautoused(Prog *p)
*lp = p->link;
continue;
}
+ if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) {
+ // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
+ // VARDEFs are interspersed with other code, and a jump might be using the
+ // VARDEF as a target. Replace with a no-op instead. A later pass will remove
+ // the no-ops.
+ p->to.type = D_NONE;
+ p->to.node = N;
+ p->as = ANOP;
+ continue;
+ }
if (p->from.type == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta;
@@ -179,17 +240,21 @@ ginscall(Node *f, int proc)
case 1: // call in new proc (go)
case 2: // deferred call (defer)
- nodreg(&reg, types[TINT64], D_CX);
- if(flag_largemodel) {
- regalloc(&r1, f->type, f);
+ nodconst(&con, types[TINT64], argsize(f->type));
+ if(widthptr == 4) {
+ nodreg(&r1, types[TINT32], D_CX);
gmove(f, &r1);
- gins(APUSHQ, &r1, N);
- regfree(&r1);
+ nodreg(&reg, types[TINT64], D_CX);
+ nodconst(&r1, types[TINT64], 32);
+ gins(ASHLQ, &r1, &reg);
+ gins(AORQ, &con, &reg);
+ gins(APUSHQ, &reg, N);
} else {
- gins(APUSHQ, f, N);
+ nodreg(&reg, types[TINT64], D_CX);
+ gmove(f, &reg);
+ gins(APUSHQ, &reg, N);
+ gins(APUSHQ, &con, N);
}
- nodconst(&con, types[TINT32], argsize(f->type));
- gins(APUSHQ, &con, N);
if(proc == 1)
ginscall(newproc, 0);
else {
@@ -197,12 +262,16 @@ ginscall(Node *f, int proc)
fatal("hasdefer=0 but has defer");
ginscall(deferproc, 0);
}
+ nodreg(&reg, types[TINT64], D_CX);
gins(APOPQ, N, &reg);
- gins(APOPQ, N, &reg);
+ if(widthptr == 8)
+ gins(APOPQ, N, &reg);
if(proc == 2) {
nodreg(&reg, types[TINT64], D_AX);
gins(ATESTQ, &reg, &reg);
- patch(gbranch(AJNE, T, -1), retpc);
+ p = gbranch(AJEQ, T, +1);
+ cgen_ret(N);
+ patch(p, pc);
}
break;
}
@@ -386,11 +455,11 @@ cgen_aret(Node *n, Node *res)
if(res->op != OREGISTER) {
regalloc(&nod2, types[tptr], res);
- gins(ALEAQ, &nod1, &nod2);
- gins(AMOVQ, &nod2, res);
+ gins(leaptr, &nod1, &nod2);
+ gins(movptr, &nod2, res);
regfree(&nod2);
} else
- gins(ALEAQ, &nod1, res);
+ gins(leaptr, &nod1, res);
}
/*
@@ -402,15 +471,15 @@ cgen_ret(Node *n)
{
Prog *p;
- genlist(n->list); // copy out args
- if(hasdefer || curfn->exit) {
- gjmp(retpc);
- return;
- }
+ if(n != N)
+ genlist(n->list); // copy out args
+ if(hasdefer)
+ ginscall(deferreturn, 0);
+ genlist(curfn->exit);
p = gins(ARET, N, N);
- if(n->op == ORETJMP) {
+ if(n != N && n->op == ORETJMP) {
p->to.type = D_EXTERN;
- p->to.sym = n->left->sym;
+ p->to.sym = linksym(n->left->sym);
}
}
@@ -633,6 +702,18 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
}
p2 = P;
+ if(nacl) {
+ // Native Client does not relay the divide-by-zero trap
+ // to the executing program, so we must insert a check
+ // for ourselves.
+ nodconst(&n4, t, 0);
+ gins(optoas(OCMP, t), &n3, &n4);
+ p1 = gbranch(optoas(ONE, t), T, +1);
+ if(panicdiv == N)
+ panicdiv = sysfunc("panicdivide");
+ ginscall(panicdiv, -1);
+ patch(p1, pc);
+ }
if(check) {
nodconst(&n4, t, -1);
gins(optoas(OCMP, t), &n3, &n4);
@@ -1025,13 +1106,13 @@ void
clearfat(Node *nl)
{
int64 w, c, q;
- Node n1, oldn1, ax, oldax;
+ Node n1, oldn1, ax, oldax, di, z;
+ Prog *p;
/* clear a fat object */
if(debug['g'])
dump("\nclearfat", nl);
-
w = nl->type->width;
// Avoid taking the address for simple enough types.
if(componentgen(N, nl))
@@ -1044,22 +1125,41 @@ clearfat(Node *nl)
agen(nl, &n1);
savex(D_AX, &ax, &oldax, N, types[tptr]);
- gconreg(AMOVQ, 0, D_AX);
+ gconreg(AMOVL, 0, D_AX);
- if(q >= 4) {
- gconreg(AMOVQ, q, D_CX);
+ if(q > 128 || (q >= 4 && nacl)) {
+ gconreg(movptr, q, D_CX);
gins(AREP, N, N); // repeat
gins(ASTOSQ, N, N); // STOQ AL,*(DI)+
+ } else if(q >= 4) {
+ p = gins(ADUFFZERO, N, N);
+ p->to.type = D_ADDR;
+ p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
+ // 2 and 128 = magic constants: see ../../pkg/runtime/asm_amd64.s
+ p->to.offset = 2*(128-q);
} else
while(q > 0) {
gins(ASTOSQ, N, N); // STOQ AL,*(DI)+
q--;
}
- if(c >= 4) {
- gconreg(AMOVQ, c, D_CX);
- gins(AREP, N, N); // repeat
- gins(ASTOSB, N, N); // STOB AL,*(DI)+
+ z = ax;
+ di = n1;
+ if(w >= 8 && c >= 4) {
+ di.op = OINDREG;
+ di.type = z.type = types[TINT64];
+ p = gins(AMOVQ, &z, &di);
+ p->to.scale = 1;
+ p->to.offset = c-8;
+ } else if(c >= 4) {
+ di.op = OINDREG;
+ di.type = z.type = types[TINT32];
+ p = gins(AMOVL, &z, &di);
+ if(c > 4) {
+ p = gins(AMOVL, &z, &di);
+ p->to.scale = 1;
+ p->to.offset = c-4;
+ }
} else
while(c > 0) {
gins(ASTOSB, N, N); // STOB AL,*(DI)+
@@ -1095,9 +1195,9 @@ expandchecks(Prog *firstp)
p->link = p1;
p1->lineno = p->lineno;
p2->lineno = p->lineno;
- p1->loc = 9999;
- p2->loc = 9999;
- p->as = ACMPQ;
+ p1->pc = 9999;
+ p2->pc = 9999;
+ p->as = cmpptr;
p->to.type = D_CONST;
p->to.offset = 0;
p1->as = AJNE;
diff --git a/src/cmd/6g/gobj.c b/src/cmd/6g/gobj.c
index a9bd5e833..04e837b13 100644
--- a/src/cmd/6g/gobj.c
+++ b/src/cmd/6g/gobj.c
@@ -32,231 +32,6 @@
#include <libc.h>
#include "gg.h"
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- BPUTLE2(b, ANAME); /* as */
- BPUTC(b, t); /* type */
- BPUTC(b, s->sym); /* sym */
-
- Bputname(b, s);
-}
-
-void
-zfile(Biobuf *b, char *p, int n)
-{
- BPUTLE2(b, ANAME);
- BPUTC(b, D_FILE);
- BPUTC(b, 1);
- BPUTC(b, '<');
- Bwrite(b, p, n);
- BPUTC(b, 0);
-}
-
-void
-zhist(Biobuf *b, int line, vlong offset)
-{
- Addr a;
-
- BPUTLE2(b, AHISTORY);
- BPUTLE4(b, line);
- zaddr(b, &zprog.from, 0, 0);
- a = zprog.to;
- if(offset != 0) {
- a.offset = offset;
- a.type = D_CONST;
- }
- zaddr(b, &a, 0, 0);
-}
-
-void
-zaddr(Biobuf *b, Addr *a, int s, int gotype)
-{
- int32 l;
- uint64 e;
- int i, t;
- char *n;
-
- t = 0;
- if(a->index != D_NONE || a->scale != 0)
- t |= T_INDEX;
- if(s != 0)
- t |= T_SYM;
- if(gotype != 0)
- t |= T_GOTYPE;
-
- switch(a->type) {
-
- case D_BRANCH:
- if(a->u.branch == nil)
- fatal("unpatched branch");
- a->offset = a->u.branch->loc;
-
- default:
- t |= T_TYPE;
-
- case D_NONE:
- if(a->offset != 0) {
- t |= T_OFFSET;
- l = a->offset;
- if((vlong)l != a->offset)
- t |= T_64;
- }
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- }
- BPUTC(b, t);
-
- if(t & T_INDEX) { /* implies index, scale */
- BPUTC(b, a->index);
- BPUTC(b, a->scale);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- BPUTLE4(b, l);
- if(t & T_64) {
- l = a->offset>>32;
- BPUTLE4(b, l);
- }
- }
- if(t & T_SYM) /* implies sym */
- BPUTC(b, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->u.dval);
- BPUTLE4(b, e);
- BPUTLE4(b, e >> 32);
- return;
- }
- if(t & T_SCONST) {
- n = a->u.sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(b, *n);
- n++;
- }
- return;
- }
- if(t & T_TYPE)
- BPUTC(b, a->type);
- if(t & T_GOTYPE)
- BPUTC(b, gotype);
-}
-
-static struct {
- struct { Sym *sym; short type; } h[NSYM];
- int sym;
-} z;
-
-static void
-zsymreset(void)
-{
- for(z.sym=0; z.sym<NSYM; z.sym++) {
- z.h[z.sym].sym = S;
- z.h[z.sym].type = 0;
- }
- z.sym = 1;
-}
-
-static int
-zsym(Sym *s, int t, int *new)
-{
- int i;
-
- *new = 0;
- if(s == S)
- return 0;
-
- i = s->sym;
- if(i < 0 || i >= NSYM)
- i = 0;
- if(z.h[i].type == t && z.h[i].sym == s)
- return i;
- i = z.sym;
- s->sym = i;
- zname(bout, s, t);
- z.h[i].sym = s;
- z.h[i].type = t;
- if(++z.sym >= NSYM)
- z.sym = 1;
- *new = 1;
- return i;
-}
-
-static int
-zsymaddr(Addr *a, int *new)
-{
- int t;
-
- t = a->type;
- if(t == D_ADDR)
- t = a->index;
- return zsym(a->sym, t, new);
-}
-
-void
-dumpfuncs(void)
-{
- Plist *pl;
- int sf, st, gf, gt, new;
- Sym *s;
- Prog *p;
-
- zsymreset();
-
- // fix up pc
- pcloc = 0;
- for(pl=plist; pl!=nil; pl=pl->link) {
- if(isblank(pl->name))
- continue;
- for(p=pl->firstpc; p!=P; p=p->link) {
- p->loc = pcloc;
- if(p->as != ADATA && p->as != AGLOBL)
- pcloc++;
- }
- }
-
- // put out functions
- for(pl=plist; pl!=nil; pl=pl->link) {
- if(isblank(pl->name))
- continue;
-
- // -S prints code; -SS prints code and data
- if(debug['S'] && (pl->name || debug['S']>1)) {
- s = S;
- if(pl->name != N)
- s = pl->name->sym;
- print("\n--- prog list \"%S\" ---\n", s);
- for(p=pl->firstpc; p!=P; p=p->link)
- print("%P\n", p);
- }
-
- for(p=pl->firstpc; p!=P; p=p->link) {
- for(;;) {
- sf = zsymaddr(&p->from, &new);
- gf = zsym(p->from.gotype, D_EXTERN, &new);
- if(new && sf == gf)
- continue;
- st = zsymaddr(&p->to, &new);
- if(new && (st == sf || st == gf))
- continue;
- gt = zsym(p->to.gotype, D_EXTERN, &new);
- if(new && (gt == sf || gt == gf || gt == st))
- continue;
- break;
- }
-
- BPUTLE2(bout, p->as);
- BPUTLE4(bout, p->lineno);
- zaddr(bout, &p->from, sf, gf);
- zaddr(bout, &p->to, st, gt);
- }
- }
-}
-
int
dsname(Sym *s, int off, char *t, int n)
{
@@ -267,7 +42,7 @@ dsname(Sym *s, int off, char *t, int n)
p->from.index = D_NONE;
p->from.offset = off;
p->from.scale = n;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->to.type = D_SCONST;
p->to.index = D_NONE;
@@ -286,7 +61,7 @@ datastring(char *s, int len, Addr *a)
sym = stringsym(s, len);
a->type = D_EXTERN;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
a->offset = widthptr+widthint; // skip header
a->etype = simtype[TINT];
@@ -303,7 +78,7 @@ datagostring(Strlit *sval, Addr *a)
sym = stringsym(sval->s, sval->len);
a->type = D_EXTERN;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
a->offset = 0; // header
a->etype = TINT32;
@@ -377,7 +152,7 @@ dstringptr(Sym *s, int off, char *str)
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
@@ -402,7 +177,7 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
datagostring(lit, &p->to);
@@ -431,27 +206,6 @@ dgostringptr(Sym *s, int off, char *str)
}
int
-duintxx(Sym *s, int off, uint64 v, int wid)
-{
- Prog *p;
-
- off = rnd(off, wid);
-
- p = gins(ADATA, N, N);
- p->from.type = D_EXTERN;
- p->from.index = D_NONE;
- p->from.sym = s;
- p->from.offset = off;
- p->from.scale = wid;
- p->to.type = D_CONST;
- p->to.index = D_NONE;
- p->to.offset = v;
- off += wid;
-
- return off;
-}
-
-int
dsymptr(Sym *s, int off, Sym *x, int xoff)
{
Prog *p;
@@ -461,12 +215,12 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
p->to.type = D_ADDR;
p->to.index = D_EXTERN;
- p->to.sym = x;
+ p->to.sym = linksym(x);
p->to.offset = xoff;
off += widthptr;
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index 7318909bb..e4d00bf41 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -46,7 +46,7 @@ clearp(Prog *p)
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
- p->loc = pcloc;
+ p->pc = pcloc;
pcloc++;
}
@@ -136,7 +136,7 @@ patch(Prog *p, Prog *to)
if(p->to.type != D_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
- p->to.offset = to->loc;
+ p->to.offset = to->pc;
}
Prog*
@@ -160,12 +160,7 @@ newplist(void)
{
Plist *pl;
- pl = mal(sizeof(*pl));
- if(plist == nil)
- plist = pl;
- else
- plast->link = pl;
- plast = pl;
+ pl = linknewplist(ctxt);
pc = mal(sizeof(*pc));
clearp(pc);
@@ -198,8 +193,8 @@ ggloblnod(Node *nam)
p = gins(AGLOBL, nam, N);
p->lineno = nam->lineno;
- p->from.gotype = ngotype(nam);
- p->to.sym = S;
+ p->from.sym->gotype = linksym(ngotype(nam));
+ p->to.sym = nil;
p->to.type = D_CONST;
p->to.offset = nam->type->width;
if(nam->readonly)
@@ -216,7 +211,7 @@ gtrack(Sym *s)
p = gins(AUSEFIELD, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
}
void
@@ -237,7 +232,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
p = gins(AGLOBL, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->to.type = D_CONST;
p->to.index = D_NONE;
p->to.offset = width;
@@ -272,7 +267,7 @@ afunclit(Addr *a, Node *n)
if(a->type == D_ADDR && a->index == D_EXTERN) {
a->type = D_EXTERN;
a->index = D_NONE;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
}
}
@@ -301,6 +296,11 @@ ginit(void)
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]++;
+
+ if(nacl) {
+ reg[D_BP]++;
+ reg[D_R15]++;
+ }
}
void
@@ -310,6 +310,11 @@ gclean(void)
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]--;
+ if(nacl) {
+ reg[D_BP]--;
+ reg[D_R15]--;
+ }
+
for(i=D_AX; i<=D_R15; i++)
if(reg[i])
@@ -457,6 +462,7 @@ Node*
nodarg(Type *t, int fp)
{
Node *n;
+ NodeList *l;
Type *first;
Iter savet;
@@ -477,6 +483,14 @@ nodarg(Type *t, int fp)
if(t->etype != TFIELD)
fatal("nodarg: not field %T", t);
+
+ if(fp == 1) {
+ for(l=curfn->dcl; l; l=l->next) {
+ n = l->n;
+ if((n->class == PPARAM || n->class == PPARAMOUT) && !isblanksym(t->sym) && n->sym == t->sym)
+ return n;
+ }
+ }
n = nod(ONAME, N, N);
n->type = t->type;
@@ -525,7 +539,16 @@ gconreg(int as, vlong c, int reg)
{
Node nr;
- nodreg(&nr, types[TINT64], reg);
+ switch(as) {
+ case AADDL:
+ case AMOVL:
+ case ALEAL:
+ nodreg(&nr, types[TINT32], reg);
+ break;
+ default:
+ nodreg(&nr, types[TINT64], reg);
+ }
+
ginscon(as, c, &nr);
}
@@ -538,10 +561,18 @@ ginscon(int as, vlong c, Node *n2)
{
Node n1, ntmp;
- nodconst(&n1, types[TINT64], c);
+ switch(as) {
+ case AADDL:
+ case AMOVL:
+ case ALEAL:
+ nodconst(&n1, types[TINT32], c);
+ break;
+ default:
+ nodconst(&n1, types[TINT64], c);
+ }
if(as != AMOVQ && (c < -(1LL<<31) || c >= 1LL<<31)) {
- // cannot have 64-bit immediokate in ADD, etc.
+ // cannot have 64-bit immediate in ADD, etc.
// instead, MOV into register first.
regalloc(&ntmp, types[TINT64], N);
gins(AMOVQ, &n1, &ntmp);
@@ -1098,10 +1129,12 @@ fixlargeoffset(Node *n)
void
naddr(Node *n, Addr *a, int canemitcode)
{
+ Sym *s;
+
a->scale = 0;
a->index = D_NONE;
a->type = D_NONE;
- a->gotype = S;
+ a->gotype = nil;
a->node = N;
a->width = 0;
if(n == N)
@@ -1119,7 +1152,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OREGISTER:
a->type = n->val.u.reg;
- a->sym = S;
+ a->sym = nil;
break;
// case OINDEX:
@@ -1144,7 +1177,7 @@ naddr(Node *n, Addr *a, int canemitcode)
case OINDREG:
a->type = n->val.u.reg+D_INDIR;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
a->offset = n->xoffset;
if(a->offset != (int32)a->offset)
yyerror("offset %lld too large for OINDREG", a->offset);
@@ -1156,20 +1189,22 @@ naddr(Node *n, Addr *a, int canemitcode)
a->etype = simtype[n->left->type->etype];
a->width = n->left->type->width;
a->offset = n->xoffset;
- a->sym = n->left->sym;
+ a->sym = linksym(n->left->sym);
a->type = D_PARAM;
a->node = n->left->orig;
break;
case OCLOSUREVAR:
+ if(!curfn->needctxt)
+ fatal("closurevar without needctxt");
a->type = D_DX+D_INDIR;
- a->sym = S;
+ a->sym = nil;
a->offset = n->xoffset;
break;
case OCFUNC:
naddr(n->left, a, canemitcode);
- a->sym = n->left->sym;
+ a->sym = linksym(n->left->sym);
break;
case ONAME:
@@ -1177,17 +1212,17 @@ naddr(Node *n, Addr *a, int canemitcode)
if(n->type != T)
a->etype = simtype[n->type->etype];
a->offset = n->xoffset;
- a->sym = n->sym;
+ s = n->sym;
a->node = n->orig;
//if(a->node >= (Node*)&n)
// fatal("stack node");
- if(a->sym == S)
- a->sym = lookup(".noname");
+ if(s == S)
+ s = lookup(".noname");
if(n->method) {
if(n->type != T)
if(n->type->sym != S)
if(n->type->sym->pkg != nil)
- a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
+ s = pkglookup(s->name, n->type->sym->pkg);
}
switch(n->class) {
@@ -1207,9 +1242,10 @@ naddr(Node *n, Addr *a, int canemitcode)
a->index = D_EXTERN;
a->type = D_ADDR;
a->width = widthptr;
- a->sym = funcsym(a->sym);
+ s = funcsym(s);
break;
}
+ a->sym = linksym(s);
break;
case OLITERAL:
@@ -1223,7 +1259,7 @@ naddr(Node *n, Addr *a, int canemitcode)
break;
case CTINT:
case CTRUNE:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
@@ -1231,12 +1267,12 @@ naddr(Node *n, Addr *a, int canemitcode)
datagostring(n->val.u.sval, a);
break;
case CTBOOL:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = n->val.u.bval;
break;
case CTNIL:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = 0;
break;
@@ -1273,7 +1309,7 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // ptr(nil)
- a->etype = simtype[TUINTPTR];
+ a->etype = simtype[tptr];
a->offset += Array_array;
a->width = widthptr;
break;
@@ -1506,12 +1542,14 @@ optoas(int op, Type *t)
case CASE(OADD, TINT32):
case CASE(OADD, TUINT32):
case CASE(OADD, TPTR32):
+ case CASE(OADDPTR, TPTR32):
a = AADDL;
break;
case CASE(OADD, TINT64):
case CASE(OADD, TUINT64):
case CASE(OADD, TPTR64):
+ case CASE(OADDPTR, TPTR64):
a = AADDQ;
break;
@@ -2042,7 +2080,7 @@ odot:
for(i=1; i<o; i++) {
if(oary[i] >= 0)
fatal("can't happen");
- gins(AMOVQ, &n1, reg);
+ gins(movptr, &n1, reg);
cgen_checknil(reg);
n1.xoffset = -(oary[i]+1);
}
@@ -2254,7 +2292,7 @@ oindex_const_sudo:
if(reg->op == OEMPTY)
regalloc(reg, types[tptr], N);
- p1 = gins(AMOVQ, N, reg);
+ p1 = gins(movptr, N, reg);
p1->from = *a;
n2 = *reg;
diff --git a/src/cmd/6g/list.c b/src/cmd/6g/list.c
deleted file mode 100644
index 9d27a6a09..000000000
--- a/src/cmd/6g/list.c
+++ /dev/null
@@ -1,364 +0,0 @@
-// Derived from 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 "gg.h"
-
-static int sconsize;
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv); // as
- fmtinstall('P', Pconv); // Prog*
- fmtinstall('D', Dconv); // Addr*
- fmtinstall('R', Rconv); // reg
- fmtinstall('Y', Yconv); // sconst
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
- char scale[40];
-
- p = va_arg(fp->args, Prog*);
- sconsize = 8;
- scale[0] = '\0';
- if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
- snprint(scale, sizeof scale, "%d,", p->from.scale);
- switch(p->as) {
- default:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
-
- case ADATA:
- sconsize = p->from.scale;
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
- p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
- break;
-
- case ATEXT:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Addr *a;
- int i;
- uint32 d1, d2;
-
- a = va_arg(fp->args, Addr*);
- i = a->type;
- if(i >= D_INDIR) {
- if(a->offset)
- snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof(str), "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- if(a->offset)
- snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
- else
- snprint(str, sizeof(str), "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(a->u.branch == nil)
- snprint(str, sizeof(str), "<nil>");
- else
- snprint(str, sizeof(str), "%d", a->u.branch->loc);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof(str), "%S+%lld(SB)", a->sym, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof(str), "%S<>+%lld(SB)", a->sym, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof(str), "%S+%lld(SP)", a->sym, a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof(str), "%S+%lld(FP)", a->sym, a->offset);
- break;
-
- case D_CONST:
- if(fp->flags & FmtLong) {
- d1 = a->offset & 0xffffffffLL;
- d2 = (a->offset>>32) & 0xffffffffLL;
- snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
- break;
- }
- snprint(str, sizeof(str), "$%lld", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof(str), "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
- if(a->gotype)
- fmtprint(fp, "{%s}", a->gotype->name);
- return 0;
-}
-
-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",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
- snprint(str, sizeof(str), "BAD_R(%d)", r);
- return fmtstrcpy(fp, str);
- }
- return fmtstrcpy(fp, regstr[r]);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-
-int
-Yconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sconsize; 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/cmd/6g/opt.h b/src/cmd/6g/opt.h
index 3dcc3d747..bf356af0c 100644
--- a/src/cmd/6g/opt.h
+++ b/src/cmd/6g/opt.h
@@ -94,6 +94,7 @@ EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
+EXTERN Bits ivar;
EXTERN Bits ovar;
EXTERN int change;
EXTERN int32 maxnr;
diff --git a/src/cmd/6g/peep.c b/src/cmd/6g/peep.c
index 5ccf90103..0f2720443 100644
--- a/src/cmd/6g/peep.c
+++ b/src/cmd/6g/peep.c
@@ -109,7 +109,7 @@ peep(Prog *firstp)
case ALEAL:
case ALEAQ:
if(regtyp(&p->to))
- if(p->from.sym != S)
+ if(p->from.sym != nil)
if(p->from.index == D_NONE || p->from.index == D_CONST)
conprop(r);
break;
@@ -306,7 +306,7 @@ pushback(Flow *r0)
if(p->as != ANOP) {
if(!regconsttyp(&p->from) || !regtyp(&p->to))
break;
- if(copyu(p, &p0->to, A) || copyu(p0, &p->to, A))
+ if(copyu(p, &p0->to, nil) || copyu(p0, &p->to, nil))
break;
}
if(p->as == ACALL)
@@ -573,6 +573,8 @@ subprop(Flow *r0)
break;
}
p = r->prog;
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ continue;
proginfo(&info, p);
if(info.flags & Call) {
if(debug['P'] && debug['v'])
@@ -682,7 +684,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
if(debug['P'])
print("; merge; f=%d", f);
}
- t = copyu(p, v2, A);
+ t = copyu(p, v2, nil);
switch(t) {
case 2: /* rar, can't split */
if(debug['P'])
@@ -720,7 +722,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
break;
}
if(!f) {
- t = copyu(p, v1, A);
+ t = copyu(p, v1, nil);
if(!f && (t == 2 || t == 3 || t == 4)) {
f = 1;
if(debug['P'])
@@ -751,7 +753,7 @@ copyu(Prog *p, Adr *v, Adr *s)
switch(p->as) {
case AJMP:
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
@@ -761,7 +763,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
case ARET:
- if(s != A)
+ if(s != nil)
return 1;
return 3;
@@ -773,7 +775,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(v->type == p->from.type)
return 2;
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
@@ -788,6 +790,8 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
}
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ return 0;
proginfo(&info, p);
if((info.reguse|info.regset) & RtoB(v->type))
@@ -803,7 +807,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(info.flags & RightWrite) {
if(copyas(&p->to, v)) {
- if(s != A)
+ if(s != nil)
return copysub(&p->from, v, s, 1);
if(copyau(&p->from, v))
return 4;
@@ -812,7 +816,7 @@ copyu(Prog *p, Adr *v, Adr *s)
}
if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->from, v, s, 1))
return 1;
return copysub(&p->to, v, s, 1);
@@ -940,7 +944,7 @@ loop:
return;
p = r->prog;
- t = copyu(p, v0, A);
+ t = copyu(p, v0, nil);
switch(t) {
case 0: // miss
case 1: // use
@@ -956,7 +960,7 @@ loop:
if(p->from.node == p0->from.node)
if(p->from.offset == p0->from.offset)
if(p->from.scale == p0->from.scale)
- if(p->from.u.vval == p0->from.u.vval)
+ if(p->from.type == D_FCONST && p->from.u.dval == p0->from.u.dval)
if(p->from.index == p0->from.index) {
excise(r);
goto loop;
diff --git a/src/cmd/6g/prog.c b/src/cmd/6g/prog.c
index 90571a21a..ee68399d5 100644
--- a/src/cmd/6g/prog.c
+++ b/src/cmd/6g/prog.c
@@ -38,9 +38,11 @@ static ProgInfo progtable[ALAST] = {
[ATEXT]= {Pseudo},
[AFUNCDATA]= {Pseudo},
[APCDATA]= {Pseudo},
- [AUNDEF]= {OK},
+ [AUNDEF]= {Break},
[AUSEFIELD]= {OK},
[ACHECKNIL]= {LeftRead},
+ [AVARDEF]= {Pseudo | RightWrite},
+ [AVARKILL]= {Pseudo | RightWrite},
// NOP is an internal no-op that also stands
// for USED and SET annotations, not the Intel opcode.
@@ -142,6 +144,7 @@ static ProgInfo progtable[ALAST] = {
[AJMP]= {Jump | Break | KillCarry},
+ [ALEAL]= {LeftAddr | RightWrite},
[ALEAQ]= {LeftAddr | RightWrite},
[AMOVBLSX]= {SizeL | LeftRead | RightWrite | Conv},
@@ -167,6 +170,7 @@ static ProgInfo progtable[ALAST] = {
[AMOVSL]= {OK, DI|SI, DI|SI},
[AMOVSQ]= {OK, DI|SI, DI|SI},
[AMOVSW]= {OK, DI|SI, DI|SI},
+ [ADUFFCOPY]= {OK, DI|SI, DI|SI|CX},
[AMOVSD]= {SizeD | LeftRead | RightWrite | Move},
[AMOVSS]= {SizeF | LeftRead | RightWrite | Move},
@@ -254,6 +258,7 @@ static ProgInfo progtable[ALAST] = {
[ASTOSL]= {OK, AX|DI, DI},
[ASTOSQ]= {OK, AX|DI, DI},
[ASTOSW]= {OK, AX|DI, DI},
+ [ADUFFZERO]= {OK, AX|DI, DI},
[ASUBB]= {SizeB | LeftRead | RightRdwr | SetCarry},
[ASUBL]= {SizeL | LeftRead | RightRdwr | SetCarry},
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
index 63fd0deca..f3b1e55de 100644
--- a/src/cmd/6g/reg.c
+++ b/src/cmd/6g/reg.c
@@ -55,30 +55,6 @@ rcmp(const void *a1, const void *a2)
}
static void
-setoutvar(void)
-{
- Type *t;
- Node *n;
- Addr a;
- Iter save;
- Bits bit;
- int z;
-
- t = structfirst(&save, getoutarg(curfn->type));
- while(t != T) {
- n = nodarg(t, 1);
- a = zprog.from;
- naddr(n, &a, 0);
- bit = mkvar(R, &a);
- for(z=0; z<BITS; z++)
- ovar.b[z] |= bit.b[z];
- t = structnext(&save);
- }
-//if(bany(&ovar))
-//print("ovars = %Q\n", ovar);
-}
-
-static void
setaddrs(Bits bit)
{
int i, n;
@@ -138,6 +114,8 @@ static char* regname[] = {
static Node* regnodes[NREGVAR];
+static void walkvardef(Node *n, Reg *r, int active);
+
void
regopt(Prog *firstp)
{
@@ -145,7 +123,7 @@ regopt(Prog *firstp)
Prog *p;
Graph *g;
ProgInfo info;
- int i, z;
+ int i, z, active;
uint32 vreg;
Bits bit;
@@ -155,9 +133,8 @@ regopt(Prog *firstp)
first = 0;
}
- fixjmp(firstp);
mergetemp(firstp);
-
+
/*
* control flow is more complicated in generated go code
* than in generated c code. define pseudo-variables for
@@ -177,12 +154,10 @@ regopt(Prog *firstp)
params.b[z] = 0;
consts.b[z] = 0;
addrs.b[z] = 0;
+ ivar.b[z] = 0;
ovar.b[z] = 0;
}
- // build list of return variables
- setoutvar();
-
/*
* pass 1
* build aux data structure
@@ -190,12 +165,18 @@ regopt(Prog *firstp)
* find use and set of variables
*/
g = flowstart(firstp, sizeof(Reg));
- if(g == nil)
+ if(g == nil) {
+ for(i=0; i<nvar; i++)
+ var[i].node->opt = nil;
return;
+ }
+
firstr = (Reg*)g->start;
for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog;
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ continue;
proginfo(&info, p);
// Avoid making variables for direct-called functions.
@@ -256,6 +237,26 @@ regopt(Prog *firstp)
dumpit("pass2", &firstr->f, 1);
/*
+ * pass 2.5
+ * iterate propagating fat vardef covering forward
+ * r->act records vars with a VARDEF since the last CALL.
+ * (r->act will be reused in pass 5 for something else,
+ * but we'll be done with it by then.)
+ */
+ active = 0;
+ for(r = firstr; r != R; r = (Reg*)r->f.link) {
+ r->f.active = 0;
+ r->act = zbits;
+ }
+ for(r = firstr; r != R; r = (Reg*)r->f.link) {
+ p = r->f.prog;
+ if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) {
+ active++;
+ walkvardef(p->to.node, r, active);
+ }
+ }
+
+ /*
* pass 3
* iterate propagating usage
* back until flow graph is complete
@@ -406,6 +407,8 @@ brk:
/*
* free aux structures. peep allocates new ones.
*/
+ for(i=0; i<nvar; i++)
+ var[i].node->opt = nil;
flowend(g);
firstr = R;
@@ -454,6 +457,32 @@ brk:
}
}
+static void
+walkvardef(Node *n, Reg *r, int active)
+{
+ Reg *r1, *r2;
+ int bn;
+ Var *v;
+
+ for(r1=r; r1!=R; r1=(Reg*)r1->f.s1) {
+ if(r1->f.active == active)
+ break;
+ r1->f.active = active;
+ if(r1->f.prog->as == AVARKILL && r1->f.prog->to.node == n)
+ break;
+ for(v=n->opt; v!=nil; v=v->nextinnode) {
+ bn = v - var;
+ r1->act.b[bn/32] |= 1L << (bn%32);
+ }
+ if(r1->f.prog->as == ACALL)
+ break;
+ }
+
+ for(r2=r; r2!=r1; r2=(Reg*)r2->f.s1)
+ if(r2->f.s2 != nil)
+ walkvardef(n, (Reg*)r2->f.s2, active);
+}
+
/*
* add mov b,rn
* just after r
@@ -467,7 +496,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1 = mal(sizeof(*p1));
clearp(p1);
- p1->loc = 9999;
+ p1->pc = 9999;
p = r->f.prog;
p1->link = p->link;
@@ -481,12 +510,12 @@ addmove(Reg *r, int bn, int rn, int f)
a->etype = v->etype;
a->type = v->name;
a->node = v->node;
- a->sym = v->node->sym;
+ a->sym = linksym(v->node->sym);
// need to clean this up with wptr and
// some of the defaults
p1->as = AMOVL;
- switch(v->etype) {
+ switch(simtype[(uchar)v->etype]) {
default:
fatal("unknown type %E", v->etype);
case TINT8:
@@ -500,7 +529,6 @@ addmove(Reg *r, int bn, int rn, int f)
break;
case TINT64:
case TUINT64:
- case TUINTPTR:
case TPTR64:
p1->as = AMOVQ;
break;
@@ -510,8 +538,6 @@ addmove(Reg *r, int bn, int rn, int f)
case TFLOAT64:
p1->as = AMOVSD;
break;
- case TINT:
- case TUINT:
case TINT32:
case TUINT32:
case TPTR32:
@@ -655,6 +681,16 @@ mkvar(Reg *r, Adr *a)
if(nvar >= NVAR) {
if(debug['w'] > 1 && node != N)
fatal("variable not optimized: %#N", node);
+
+ // If we're not tracking a word in a variable, mark the rest as
+ // having its address taken, so that we keep the whole thing
+ // live at all calls. otherwise we might optimize away part of
+ // a variable but not all of it.
+ for(i=0; i<nvar; i++) {
+ v = var+i;
+ if(v->node == node)
+ v->addr = 1;
+ }
goto none;
}
@@ -667,11 +703,13 @@ mkvar(Reg *r, Adr *a)
v->width = w;
v->addr = flag; // funny punning
v->node = node;
-
- if(debug['R'])
- print("bit=%2d et=%2E w=%d+%lld %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
-
- ostats.nvar++;
+
+ // node->opt is the head of a linked list
+ // of Vars within the given Node, so that
+ // we can start at a Var and find all the other
+ // Vars in the same Go variable.
+ v->nextinnode = node->opt;
+ node->opt = v;
bit = blsh(i);
if(n == D_EXTERN || n == D_STATIC)
@@ -681,6 +719,46 @@ mkvar(Reg *r, Adr *a)
for(z=0; z<BITS; z++)
params.b[z] |= bit.b[z];
+ if(node->class == PPARAM)
+ for(z=0; z<BITS; z++)
+ ivar.b[z] |= bit.b[z];
+ if(node->class == PPARAMOUT)
+ for(z=0; z<BITS; z++)
+ ovar.b[z] |= bit.b[z];
+
+ // Treat values with their address taken as live at calls,
+ // because the garbage collector's liveness analysis in ../gc/plive.c does.
+ // These must be consistent or else we will elide stores and the garbage
+ // collector will see uninitialized data.
+ // The typical case where our own analysis is out of sync is when the
+ // node appears to have its address taken but that code doesn't actually
+ // get generated and therefore doesn't show up as an address being
+ // taken when we analyze the instruction stream.
+ // One instance of this case is when a closure uses the same name as
+ // an outer variable for one of its own variables declared with :=.
+ // The parser flags the outer variable as possibly shared, and therefore
+ // sets addrtaken, even though it ends up not being actually shared.
+ // If we were better about _ elision, _ = &x would suffice too.
+ // The broader := in a closure problem is mentioned in a comment in
+ // closure.c:/^typecheckclosure and dcl.c:/^oldname.
+ if(node->addrtaken)
+ v->addr = 1;
+
+ // Disable registerization for globals, because:
+ // (1) we might panic at any time and we want the recovery code
+ // to see the latest values (issue 1304).
+ // (2) we don't know what pointers might point at them and we want
+ // loads via those pointers to see updated values and vice versa (issue 7995).
+ //
+ // Disable registerization for results if using defer, because the deferred func
+ // might recover and return, causing the current values to be used.
+ if(node->class == PEXTERN || (hasdefer && node->class == PPARAMOUT))
+ v->addr = 1;
+
+ if(debug['R'])
+ print("bit=%2d et=%2E w=%lld+%lld %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
+ ostats.nvar++;
+
return bit;
none:
@@ -691,7 +769,8 @@ void
prop(Reg *r, Bits ref, Bits cal)
{
Reg *r1, *r2;
- int z;
+ int z, i, j;
+ Var *v, *v1;
for(r1 = r; r1 != R; r1 = (Reg*)r1->f.p1) {
for(z=0; z<BITS; z++) {
@@ -710,10 +789,61 @@ prop(Reg *r, Bits ref, Bits cal)
case ACALL:
if(noreturn(r1->f.prog))
break;
+
+ // Mark all input variables (ivar) as used, because that's what the
+ // liveness bitmaps say. The liveness bitmaps say that so that a
+ // panic will not show stale values in the parameter dump.
+ // Mark variables with a recent VARDEF (r1->act) as used,
+ // so that the optimizer flushes initializations to memory,
+ // so that if a garbage collection happens during this CALL,
+ // the collector will see initialized memory. Again this is to
+ // match what the liveness bitmaps say.
for(z=0; z<BITS; z++) {
- cal.b[z] |= ref.b[z] | externs.b[z];
+ cal.b[z] |= ref.b[z] | externs.b[z] | ivar.b[z] | r1->act.b[z];
ref.b[z] = 0;
}
+
+ // cal.b is the current approximation of what's live across the call.
+ // Every bit in cal.b is a single stack word. For each such word,
+ // find all the other tracked stack words in the same Go variable
+ // (struct/slice/string/interface) and mark them live too.
+ // This is necessary because the liveness analysis for the garbage
+ // collector works at variable granularity, not at word granularity.
+ // It is fundamental for slice/string/interface: the garbage collector
+ // needs the whole value, not just some of the words, in order to
+ // interpret the other bits correctly. Specifically, slice needs a consistent
+ // ptr and cap, string needs a consistent ptr and len, and interface
+ // needs a consistent type word and data word.
+ for(z=0; z<BITS; z++) {
+ if(cal.b[z] == 0)
+ continue;
+ for(i=0; i<32; i++) {
+ if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0)
+ continue;
+ v = var+z*32+i;
+ if(v->node->opt == nil) // v represents fixed register, not Go variable
+ continue;
+
+ // v->node->opt is the head of a linked list of Vars
+ // corresponding to tracked words from the Go variable v->node.
+ // Walk the list and set all the bits.
+ // For a large struct this could end up being quadratic:
+ // after the first setting, the outer loop (for z, i) would see a 1 bit
+ // for all of the remaining words in the struct, and for each such
+ // word would go through and turn on all the bits again.
+ // To avoid the quadratic behavior, we only turn on the bits if
+ // v is the head of the list or if the head's bit is not yet turned on.
+ // This will set the bits at most twice, keeping the overall loop linear.
+ v1 = v->node->opt;
+ j = v1 - var;
+ if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
+ for(; v1 != nil; v1 = v1->nextinnode) {
+ j = v1 - var;
+ cal.b[j/32] |= 1<<(j&31);
+ }
+ }
+ }
+ }
break;
case ATEXT:
@@ -729,17 +859,6 @@ prop(Reg *r, Bits ref, Bits cal)
ref.b[z] = 0;
}
break;
-
- default:
- // Work around for issue 1304:
- // flush modified globals before each instruction.
- for(z=0; z<BITS; z++) {
- cal.b[z] |= externs.b[z];
- // issue 4066: flush modified return variables in case of panic
- if(hasdefer)
- cal.b[z] |= ovar.b[z];
- }
- break;
}
for(z=0; z<BITS; z++) {
ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
@@ -860,12 +979,11 @@ paint1(Reg *r, int bn)
for(;;) {
r->act.b[z] |= bb;
- if(r->use1.b[z] & bb) {
- change += CREF * r->f.loop;
- }
-
- if((r->use2.b[z]|r->set.b[z]) & bb) {
- change += CREF * r->f.loop;
+ if(r->f.prog->as != ANOP) { // don't give credit for NOPs
+ if(r->use1.b[z] & bb)
+ change += CREF * r->f.loop;
+ if((r->use2.b[z]|r->set.b[z]) & bb)
+ change += CREF * r->f.loop;
}
if(STORE(r) & r->regdiff.b[z] & bb) {
@@ -906,7 +1024,7 @@ regset(Reg *r, uint32 bb)
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
if(v.type == 0)
fatal("zero v.type for %#ux", b);
- c = copyu(r->f.prog, &v, A);
+ c = copyu(r->f.prog, &v, nil);
if(c == 3)
set |= b;
bb &= ~b;
@@ -925,7 +1043,7 @@ reguse(Reg *r, uint32 bb)
v = zprog.from;
while(b = bb & ~(bb-1)) {
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
- c = copyu(r->f.prog, &v, A);
+ c = copyu(r->f.prog, &v, nil);
if(c == 1 || c == 2 || c == 4)
set |= b;
bb &= ~b;
@@ -1067,8 +1185,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
void
addreg(Adr *a, int rn)
{
-
- a->sym = 0;
+ a->sym = nil;
a->offset = 0;
a->type = rn;
@@ -1088,6 +1205,8 @@ int
BtoR(int32 b)
{
b &= 0xffffL;
+ if(nacl)
+ b &= ~((1<<(D_BP-D_AX)) | (1<<(D_R15-D_AX)));
if(b == 0)
return 0;
return bitno(b) + D_AX;
@@ -1176,14 +1295,14 @@ dumpit(char *str, Flow *r0, int isreg)
if(r1 != nil) {
print(" pred:");
for(; r1 != nil; r1 = r1->p2link)
- print(" %.4ud", r1->prog->loc);
+ print(" %.4ud", (int)r1->prog->pc);
print("\n");
}
// r1 = r->s1;
// if(r1 != R) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4ud", r1->prog->loc);
+// print(" %.4ud", (int)r1->prog->pc);
// print("\n");
// }
}
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h
index 5fa73a65b..1e2a1488f 100644
--- a/src/cmd/6l/6.out.h
+++ b/src/cmd/6l/6.out.h
@@ -762,6 +762,10 @@ enum as
AFUNCDATA,
APCDATA,
ACHECKNIL,
+ AVARDEF,
+ AVARKILL,
+ ADUFFCOPY,
+ ADUFFZERO,
ALAST
};
@@ -846,27 +850,21 @@ enum
D_DR = 95,
D_TR = 103,
- D_NONE = 111,
+ D_TLS = 111,
+ D_NONE = 112,
- D_BRANCH = 112,
- D_EXTERN = 113,
- D_STATIC = 114,
- D_AUTO = 115,
- D_PARAM = 116,
- D_CONST = 117,
- D_FCONST = 118,
- D_SCONST = 119,
- D_ADDR = 120,
-
- D_FILE,
- D_FILE1,
+ D_BRANCH = 113,
+ D_EXTERN = 114,
+ D_STATIC = 115,
+ D_AUTO = 116,
+ D_PARAM = 117,
+ D_CONST = 118,
+ D_FCONST = 119,
+ D_SCONST = 120,
+ D_ADDR = 121,
D_INDIR, /* additive */
- D_SIZE = D_INDIR + D_INDIR, /* 6l internal */
- D_PCREL,
- D_TLS,
-
T_TYPE = 1<<0,
T_INDEX = 1<<1,
T_OFFSET = 1<<2,
@@ -890,15 +888,3 @@ enum
* this is the ranlib header
*/
#define SYMDEF "__.GOSYMDEF"
-
-/*
- * this is the simulated IEEE floating point
- */
-typedef struct ieee Ieee;
-struct ieee
-{
- int32 l; /* contains ls-man 0xffffffff */
- int32 h; /* contains sign 0x80000000
- exp 0x7ff00000
- ms-man 0x000fffff */
-};
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index a09cc9727..e251e32ca 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -44,49 +44,22 @@ char freebsddynld[] = "/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/libexec/ld.elf_so";
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
+char solarisdynld[] = "/lib/amd64/ld.so.1";
char zeroes[32];
-vlong
-entryvalue(void)
-{
- char *a;
- Sym *s;
-
- a = INITENTRY;
- if(*a >= '0' && *a <= '9')
- return atolwhex(a);
- s = lookup(a, 0);
- if(s->type == 0)
- return INITTEXT;
- if(s->type != STEXT)
- diag("entry not text: %s", s->name);
- return s->value;
-}
-
-vlong
-datoff(vlong addr)
-{
- if(addr >= segdata.vaddr)
- return addr - segdata.vaddr + segdata.fileoff;
- if(addr >= segtext.vaddr)
- return addr - segtext.vaddr + segtext.fileoff;
- diag("datoff %#llx", addr);
- return 0;
-}
-
static int
needlib(char *name)
{
char *p;
- Sym *s;
+ LSym *s;
if(*name == '\0')
return 0;
/* reuse hash code in symbol table */
p = smprint(".elfload.%s", name);
- s = lookup(p, 0);
+ s = linklookup(ctxt, p, 0);
free(p);
if(s->type == 0) {
s->type = 100; // avoid SDATA, etc.
@@ -97,24 +70,24 @@ needlib(char *name)
int nelfsym = 1;
-static void addpltsym(Sym*);
-static void addgotsym(Sym*);
+static void addpltsym(LSym*);
+static void addgotsym(LSym*);
void
-adddynrela(Sym *rela, Sym *s, Reloc *r)
+adddynrela(LSym *rela, LSym *s, Reloc *r)
{
- addaddrplus(rela, s, r->off);
- adduint64(rela, R_X86_64_RELATIVE);
- addaddrplus(rela, r->sym, r->add); // Addend
+ addaddrplus(ctxt, rela, s, r->off);
+ adduint64(ctxt, rela, R_X86_64_RELATIVE);
+ addaddrplus(ctxt, rela, r->sym, r->add); // Addend
}
void
-adddynrel(Sym *s, Reloc *r)
+adddynrel(LSym *s, Reloc *r)
{
- Sym *targ, *rela, *got;
+ LSym *targ, *rela, *got;
targ = r->sym;
- cursym = s;
+ ctxt->cursym = s;
switch(r->type) {
default:
@@ -130,16 +103,16 @@ adddynrel(Sym *s, Reloc *r)
diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ->name);
if(targ->type == 0 || targ->type == SXREF)
diag("unknown symbol %s in pcrel", targ->name);
- r->type = D_PCREL;
+ r->type = R_PCREL;
r->add += 4;
return;
case 256 + R_X86_64_PLT32:
- r->type = D_PCREL;
+ r->type = R_PCREL;
r->add += 4;
if(targ->type == SDYNIMPORT) {
addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add += targ->plt;
}
return;
@@ -150,7 +123,7 @@ adddynrel(Sym *s, Reloc *r)
if(r->off >= 2 && s->p[r->off-2] == 0x8b) {
// turn MOVQ of GOT entry into LEAQ of symbol itself
s->p[r->off-2] = 0x8d;
- r->type = D_PCREL;
+ r->type = R_PCREL;
r->add += 4;
return;
}
@@ -158,8 +131,8 @@ adddynrel(Sym *s, Reloc *r)
// TODO: just needs relocation, no need to put in .dynsym
}
addgotsym(targ);
- r->type = D_PCREL;
- r->sym = lookup(".got", 0);
+ r->type = R_PCREL;
+ r->sym = linklookup(ctxt, ".got", 0);
r->add += 4;
r->add += targ->got;
return;
@@ -167,7 +140,7 @@ adddynrel(Sym *s, Reloc *r)
case 256 + R_X86_64_64:
if(targ->type == SDYNIMPORT)
diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ->name);
- r->type = D_ADDR;
+ r->type = R_ADDR;
return;
// Handle relocations found in Mach-O object files.
@@ -175,7 +148,7 @@ adddynrel(Sym *s, Reloc *r)
case 512 + MACHO_X86_64_RELOC_SIGNED*2 + 0:
case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 0:
// TODO: What is the difference between all these?
- r->type = D_ADDR;
+ r->type = R_ADDR;
if(targ->type == SDYNIMPORT)
diag("unexpected reloc for dynamic symbol %s", targ->name);
return;
@@ -183,9 +156,9 @@ adddynrel(Sym *s, Reloc *r)
case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 1:
if(targ->type == SDYNIMPORT) {
addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = targ->plt;
- r->type = D_PCREL;
+ r->type = R_PCREL;
return;
}
// fall through
@@ -194,7 +167,7 @@ adddynrel(Sym *s, Reloc *r)
case 512 + MACHO_X86_64_RELOC_SIGNED_1*2 + 1:
case 512 + MACHO_X86_64_RELOC_SIGNED_2*2 + 1:
case 512 + MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
- r->type = D_PCREL;
+ r->type = R_PCREL;
if(targ->type == SDYNIMPORT)
diag("unexpected pc-relative reloc for dynamic symbol %s", targ->name);
return;
@@ -208,7 +181,7 @@ adddynrel(Sym *s, Reloc *r)
return;
}
s->p[r->off-2] = 0x8d;
- r->type = D_PCREL;
+ r->type = R_PCREL;
return;
}
// fall through
@@ -216,8 +189,8 @@ adddynrel(Sym *s, Reloc *r)
if(targ->type != SDYNIMPORT)
diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
addgotsym(targ);
- r->type = D_PCREL;
- r->sym = lookup(".got", 0);
+ r->type = R_PCREL;
+ r->sym = linklookup(ctxt, ".got", 0);
r->add += targ->got;
return;
}
@@ -227,24 +200,34 @@ adddynrel(Sym *s, Reloc *r)
return;
switch(r->type) {
- case D_PCREL:
+ case R_CALL:
+ case R_PCREL:
addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = targ->plt;
return;
- case D_ADDR:
+ case R_ADDR:
+ if(s->type == STEXT && iself) {
+ // The code is asking for the address of an external
+ // function. We provide it with the address of the
+ // correspondent GOT symbol.
+ addgotsym(targ);
+ r->sym = linklookup(ctxt, ".got", 0);
+ r->add += targ->got;
+ return;
+ }
if(s->type != SDATA)
break;
if(iself) {
- adddynsym(targ);
- rela = lookup(".rela", 0);
- addaddrplus(rela, s, r->off);
+ adddynsym(ctxt, targ);
+ rela = linklookup(ctxt, ".rela", 0);
+ addaddrplus(ctxt, rela, s, r->off);
if(r->siz == 8)
- adduint64(rela, ELF64_R_INFO(targ->dynid, R_X86_64_64));
+ adduint64(ctxt, rela, ELF64_R_INFO(targ->dynid, R_X86_64_64));
else
- adduint64(rela, ELF64_R_INFO(targ->dynid, R_X86_64_32));
- adduint64(rela, r->add);
+ adduint64(ctxt, rela, ELF64_R_INFO(targ->dynid, R_X86_64_32));
+ adduint64(ctxt, rela, r->add);
r->type = 256; // ignore during relocsym
return;
}
@@ -259,22 +242,22 @@ adddynrel(Sym *s, Reloc *r)
// just in case the C code assigns to the variable,
// and of course it only works for single pointers,
// but we only need to support cgo and that's all it needs.
- adddynsym(targ);
- got = lookup(".got", 0);
+ adddynsym(ctxt, targ);
+ got = linklookup(ctxt, ".got", 0);
s->type = got->type | SSUB;
s->outer = got;
s->sub = got->sub;
got->sub = s;
s->value = got->size;
- adduint64(got, 0);
- adduint32(lookup(".linkedit.got", 0), targ->dynid);
+ adduint64(ctxt, got, 0);
+ adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), targ->dynid);
r->type = 256; // ignore during relocsym
return;
}
break;
}
- cursym = s;
+ ctxt->cursym = s;
diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
}
@@ -290,7 +273,7 @@ elfreloc1(Reloc *r, vlong sectoff)
default:
return -1;
- case D_ADDR:
+ case R_ADDR:
if(r->siz == 4)
VPUT(R_X86_64_32 | (uint64)elfsym<<32);
else if(r->siz == 8)
@@ -299,14 +282,25 @@ elfreloc1(Reloc *r, vlong sectoff)
return -1;
break;
- case D_PCREL:
+ case R_TLS_LE:
if(r->siz == 4)
- VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
+ VPUT(R_X86_64_TPOFF32 | (uint64)elfsym<<32);
else
return -1;
break;
+
+ case R_CALL:
+ case R_PCREL:
+ if(r->siz == 4) {
+ if(r->xsym->type == SDYNIMPORT)
+ VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
+ else
+ VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
+ } else
+ return -1;
+ break;
- case D_TLS:
+ case R_TLS:
if(r->siz == 4) {
if(flag_shared)
VPUT(R_X86_64_GOTTPOFF | (uint64)elfsym<<32);
@@ -325,7 +319,7 @@ int
machoreloc1(Reloc *r, vlong sectoff)
{
uint32 v;
- Sym *rs;
+ LSym *rs;
rs = r->xsym;
@@ -347,10 +341,11 @@ machoreloc1(Reloc *r, vlong sectoff)
switch(r->type) {
default:
return -1;
- case D_ADDR:
+ case R_ADDR:
v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
break;
- case D_PCREL:
+ case R_CALL:
+ case R_PCREL:
v |= 1<<24; // pc-relative bit
v |= MACHO_X86_64_RELOC_BRANCH<<28;
break;
@@ -379,7 +374,7 @@ machoreloc1(Reloc *r, vlong sectoff)
}
int
-archreloc(Reloc *r, Sym *s, vlong *val)
+archreloc(Reloc *r, LSym *s, vlong *val)
{
USED(r);
USED(s);
@@ -390,68 +385,68 @@ archreloc(Reloc *r, Sym *s, vlong *val)
void
elfsetupplt(void)
{
- Sym *plt, *got;
+ LSym *plt, *got;
- plt = lookup(".plt", 0);
- got = lookup(".got.plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
+ got = linklookup(ctxt, ".got.plt", 0);
if(plt->size == 0) {
// pushq got+8(IP)
- adduint8(plt, 0xff);
- adduint8(plt, 0x35);
- addpcrelplus(plt, got, 8);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x35);
+ addpcrelplus(ctxt, plt, got, 8);
// jmpq got+16(IP)
- adduint8(plt, 0xff);
- adduint8(plt, 0x25);
- addpcrelplus(plt, got, 16);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x25);
+ addpcrelplus(ctxt, plt, got, 16);
// nopl 0(AX)
- adduint32(plt, 0x00401f0f);
+ adduint32(ctxt, plt, 0x00401f0f);
// assume got->size == 0 too
- addaddrplus(got, lookup(".dynamic", 0), 0);
- adduint64(got, 0);
- adduint64(got, 0);
+ addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0);
+ adduint64(ctxt, got, 0);
+ adduint64(ctxt, got, 0);
}
}
static void
-addpltsym(Sym *s)
+addpltsym(LSym *s)
{
if(s->plt >= 0)
return;
- adddynsym(s);
+ adddynsym(ctxt, s);
if(iself) {
- Sym *plt, *got, *rela;
+ LSym *plt, *got, *rela;
- plt = lookup(".plt", 0);
- got = lookup(".got.plt", 0);
- rela = lookup(".rela.plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
+ got = linklookup(ctxt, ".got.plt", 0);
+ rela = linklookup(ctxt, ".rela.plt", 0);
if(plt->size == 0)
elfsetupplt();
// jmpq *got+size(IP)
- adduint8(plt, 0xff);
- adduint8(plt, 0x25);
- addpcrelplus(plt, got, got->size);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x25);
+ addpcrelplus(ctxt, plt, got, got->size);
// add to got: pointer to current pos in plt
- addaddrplus(got, plt, plt->size);
+ addaddrplus(ctxt, got, plt, plt->size);
// pushq $x
- adduint8(plt, 0x68);
- adduint32(plt, (got->size-24-8)/8);
+ adduint8(ctxt, plt, 0x68);
+ adduint32(ctxt, plt, (got->size-24-8)/8);
// jmpq .plt
- adduint8(plt, 0xe9);
- adduint32(plt, -(plt->size+4));
+ adduint8(ctxt, plt, 0xe9);
+ adduint32(ctxt, plt, -(plt->size+4));
// rela
- addaddrplus(rela, got, got->size-8);
- adduint64(rela, ELF64_R_INFO(s->dynid, R_X86_64_JMP_SLOT));
- adduint64(rela, 0);
+ addaddrplus(ctxt, rela, got, got->size-8);
+ adduint64(ctxt, rela, ELF64_R_INFO(s->dynid, R_X86_64_JMP_SLOT));
+ adduint64(ctxt, rela, 0);
s->plt = plt->size - 16;
} else if(HEADTYPE == Hdarwin) {
@@ -465,53 +460,53 @@ addpltsym(Sym *s)
// http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
// has details about what we're avoiding.
- Sym *plt;
+ LSym *plt;
addgotsym(s);
- plt = lookup(".plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
- adduint32(lookup(".linkedit.plt", 0), s->dynid);
+ adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid);
// jmpq *got+size(IP)
s->plt = plt->size;
- adduint8(plt, 0xff);
- adduint8(plt, 0x25);
- addpcrelplus(plt, lookup(".got", 0), s->got);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x25);
+ addpcrelplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got);
} else {
diag("addpltsym: unsupported binary format");
}
}
static void
-addgotsym(Sym *s)
+addgotsym(LSym *s)
{
- Sym *got, *rela;
+ LSym *got, *rela;
if(s->got >= 0)
return;
- adddynsym(s);
- got = lookup(".got", 0);
+ adddynsym(ctxt, s);
+ got = linklookup(ctxt, ".got", 0);
s->got = got->size;
- adduint64(got, 0);
+ adduint64(ctxt, got, 0);
if(iself) {
- rela = lookup(".rela", 0);
- addaddrplus(rela, got, s->got);
- adduint64(rela, ELF64_R_INFO(s->dynid, R_X86_64_GLOB_DAT));
- adduint64(rela, 0);
+ rela = linklookup(ctxt, ".rela", 0);
+ addaddrplus(ctxt, rela, got, s->got);
+ adduint64(ctxt, rela, ELF64_R_INFO(s->dynid, R_X86_64_GLOB_DAT));
+ adduint64(ctxt, rela, 0);
} else if(HEADTYPE == Hdarwin) {
- adduint32(lookup(".linkedit.got", 0), s->dynid);
+ adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid);
} else {
diag("addgotsym: unsupported binary format");
}
}
void
-adddynsym(Sym *s)
+adddynsym(Link *ctxt, LSym *s)
{
- Sym *d;
+ LSym *d;
int t;
char *name;
@@ -521,24 +516,24 @@ adddynsym(Sym *s)
if(iself) {
s->dynid = nelfsym++;
- d = lookup(".dynsym", 0);
+ d = linklookup(ctxt, ".dynsym", 0);
name = s->extname;
- adduint32(d, addstring(lookup(".dynstr", 0), name));
+ adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
/* type */
t = STB_GLOBAL << 4;
if(s->cgoexport && (s->type&SMASK) == STEXT)
t |= STT_FUNC;
else
t |= STT_OBJECT;
- adduint8(d, t);
+ adduint8(ctxt, d, t);
/* reserved */
- adduint8(d, 0);
+ adduint8(ctxt, d, 0);
/* section where symbol is defined */
if(s->type == SDYNIMPORT)
- adduint16(d, SHN_UNDEF);
+ adduint16(ctxt, d, SHN_UNDEF);
else {
switch(s->type) {
default:
@@ -555,21 +550,21 @@ adddynsym(Sym *s)
t = 14;
break;
}
- adduint16(d, t);
+ adduint16(ctxt, d, t);
}
/* value */
if(s->type == SDYNIMPORT)
- adduint64(d, 0);
+ adduint64(ctxt, d, 0);
else
- addaddr(d, s);
+ addaddr(ctxt, d, s);
/* size of object */
- adduint64(d, s->size);
+ adduint64(ctxt, d, s->size);
if(!(s->cgoexport & CgoExportDynamic) && s->dynimplib && needlib(s->dynimplib)) {
- elfwritedynent(lookup(".dynamic", 0), DT_NEEDED,
- addstring(lookup(".dynstr", 0), s->dynimplib));
+ elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED,
+ addstring(linklookup(ctxt, ".dynstr", 0), s->dynimplib));
}
} else if(HEADTYPE == Hdarwin) {
diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
@@ -583,16 +578,16 @@ adddynsym(Sym *s)
void
adddynlib(char *lib)
{
- Sym *s;
+ LSym *s;
if(!needlib(lib))
return;
if(iself) {
- s = lookup(".dynstr", 0);
+ s = linklookup(ctxt, ".dynstr", 0);
if(s->size == 0)
addstring(s, "");
- elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib));
+ elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
} else if(HEADTYPE == Hdarwin) {
machoadddynlib(lib);
} else {
@@ -607,7 +602,7 @@ asmb(void)
int i;
vlong vl, symo, dwarfoff, machlink;
Section *sect;
- Sym *sym;
+ LSym *sym;
if(debug['v'])
Bprint(&bso, "%5.2f asmb\n", cputime());
@@ -662,8 +657,7 @@ asmb(void)
switch(HEADTYPE) {
default:
diag("unknown header type %d", HEADTYPE);
- case Hplan9x32:
- case Hplan9x64:
+ case Hplan9:
case Helf:
break;
case Hdarwin:
@@ -674,8 +668,10 @@ asmb(void)
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
debug['8'] = 1; /* 64-bit addresses */
break;
+ case Hnacl:
case Hwindows:
break;
}
@@ -690,7 +686,7 @@ asmb(void)
Bflush(&bso);
switch(HEADTYPE) {
default:
- case Hplan9x64:
+ case Hplan9:
case Helf:
debug['s'] = 1;
symo = HEADR+segtext.len+segdata.filelen;
@@ -703,6 +699,8 @@ asmb(void)
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
+ case Hnacl:
symo = rnd(HEADR+segtext.len, INITRND)+rnd(segrodata.len, INITRND)+segdata.filelen;
symo = rnd(symo, INITRND);
break;
@@ -729,11 +727,11 @@ asmb(void)
elfemitreloc();
}
break;
- case Hplan9x64:
+ case Hplan9:
asmplan9sym();
cflush();
- sym = lookup("pclntab", 0);
+ sym = linklookup(ctxt, "pclntab", 0);
if(sym != nil) {
lcsize = sym->np;
for(i=0; i < lcsize; i++)
@@ -761,7 +759,7 @@ asmb(void)
cseek(0L);
switch(HEADTYPE) {
default:
- case Hplan9x64: /* plan9 */
+ case Hplan9: /* plan9 */
magic = 4*26*26+7;
magic |= 0x00008000; /* fat header */
lputb(magic); /* magic */
@@ -775,17 +773,6 @@ asmb(void)
lputb(lcsize); /* line offsets */
vputb(vl); /* va of entry */
break;
- case Hplan9x32: /* plan9 */
- magic = 4*26*26+7;
- lputb(magic); /* magic */
- lputb(segtext.filelen); /* sizes */
- lputb(segdata.filelen);
- lputb(segdata.len - segdata.filelen);
- lputb(symsize); /* nsyms */
- lputb(entryvalue()); /* va of entry */
- lputb(spsize); /* sp offsets */
- lputb(lcsize); /* line offsets */
- break;
case Hdarwin:
asmbmacho();
break;
@@ -794,6 +781,8 @@ asmb(void)
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
+ case Hnacl:
asmbelf(symo);
break;
case Hwindows:
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
index ecab867e4..7303910a6 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -31,6 +31,7 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
+#include <link.h>
#include "6.out.h"
#ifndef EXTERN
@@ -40,8 +41,6 @@
enum
{
thechar = '6',
- PtrSize = 8,
- IntSize = 8,
MaxAlign = 32, // max data alignment
// Loop alignment constants:
@@ -63,147 +62,13 @@ enum
FuncAlign = 16
};
-#define P ((Prog*)0)
-#define S ((Sym*)0)
-#define TNAME (cursym?cursym->name:noname)
-
-typedef struct Adr Adr;
-typedef struct Prog Prog;
-typedef struct Sym Sym;
-typedef struct Auto Auto;
-typedef struct Optab Optab;
-typedef struct Movtab Movtab;
-typedef struct Reloc Reloc;
-
-struct Adr
-{
- union
- {
- vlong u0offset;
- char u0scon[8];
- Prog *u0cond; /* not used, but should be D_BRANCH */
- Ieee u0ieee;
- char *u0sbig;
- } u0;
- Sym* sym;
- short type;
- char index;
- char scale;
-};
-
-#define offset u0.u0offset
-#define scon u0.u0scon
-#define cond u0.u0cond
-#define ieee u0.u0ieee
-#define sbig u0.u0sbig
-
-struct Reloc
-{
- int32 off;
- uchar siz;
- uchar done;
- int32 type;
- int64 add;
- int64 xadd;
- Sym* sym;
- Sym* xsym;
-};
-
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* forwd;
- Prog* comefrom;
- Prog* link;
- Prog* pcond; /* work on this */
- vlong pc;
- int32 spadj;
- int32 line;
- short as;
- char ft; /* oclass cache */
- char tt;
- uchar mark; /* work on these */
- uchar back;
-
- char width; /* fake for DATA */
- char mode; /* 16, 32, or 64 */
-};
-#define datasize from.scale
-#define textflag from.scale
-#define iscall(p) ((p)->as == ACALL)
-
-struct Auto
-{
- Sym* asym;
- Auto* link;
- int32 aoffset;
- short type;
- Sym* gotype;
-};
-struct Sym
-{
- char* name;
- char* extname; // name used in external object files
- short type;
- short version;
- uchar dupok;
- uchar reachable;
- uchar cgoexport;
- uchar special;
- uchar stkcheck;
- uchar hide;
- int32 dynid;
- int32 sig;
- int32 plt;
- int32 got;
- int32 align; // if non-zero, required alignment in bytes
- int32 elfsym;
- int32 args; // size of stack frame incoming arguments area
- Sym* hash; // in hash table
- Sym* allsym; // in all symbol list
- Sym* next; // in text or data list
- Sym* sub; // in SSUB list
- Sym* outer; // container of sub
- Sym* reachparent;
- Sym* queue;
- vlong value;
- vlong size;
- Sym* gotype;
- char* file;
- char* dynimplib;
- char* dynimpvers;
- struct Section* sect;
- struct Hist* hist; // for ATEXT
-
- // STEXT
- Auto* autom;
- Prog* text;
-
- // SDATA, SBSS
- uchar* p;
- int32 np;
- int32 maxp;
- Reloc* r;
- int32 nr;
- int32 maxr;
-};
-struct Optab
-{
- short as;
- uchar* ytab;
- uchar prefix;
- uchar op[23];
-};
-struct Movtab
-{
- short as;
- uchar ft;
- uchar tt;
- uchar code;
- uchar op[4];
-};
+EXTERN int PtrSize;
+EXTERN int IntSize;
+EXTERN int RegSize;
+#define P ((Prog*)0)
+#define S ((LSym*)0)
+#define TNAME (ctxt->cursym?ctxt->cursym->name:noname)
enum
{
MINSIZ = 8,
@@ -211,239 +76,42 @@ enum
MINLC = 1,
MAXIO = 8192,
MAXHIST = 40, /* limit of path elements for history symbols */
-
- 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,
- Ymax,
-
- Zxxx = 0,
-
- Zlit,
- Zlitm_r,
- Z_rp,
- Zbr,
- Zcall,
- 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 */
};
-#pragma varargck type "A" uint
-#pragma varargck type "D" Adr*
#pragma varargck type "I" uchar*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-#pragma varargck type "i" char*
-EXTERN int32 HEADR;
-EXTERN int32 HEADTYPE;
-EXTERN int32 INITRND;
-EXTERN int64 INITTEXT;
-EXTERN int64 INITDAT;
-EXTERN char* INITENTRY; /* entry point */
-EXTERN char* pcstr;
-EXTERN Auto* curauto;
-EXTERN Auto* curhist;
-EXTERN Prog* curp;
-EXTERN Sym* cursym;
-EXTERN Sym* datap;
+EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN char literal[32];
-EXTERN Sym* textp;
-EXTERN Sym* etextp;
-EXTERN char ycover[Ymax*Ymax];
-EXTERN uchar* andptr;
-EXTERN uchar* rexptr;
-EXTERN uchar and[30];
-EXTERN int reg[D_NONE];
-EXTERN int regrex[D_NONE+1];
EXTERN int32 lcsize;
-EXTERN int nerrors;
-EXTERN char* noname;
-EXTERN char* outfile;
-EXTERN vlong pc;
-EXTERN char* interpreter;
EXTERN char* rpath;
EXTERN int32 spsize;
-EXTERN Sym* symlist;
+EXTERN LSym* symlist;
EXTERN int32 symsize;
-EXTERN int tlsoffset;
-EXTERN Prog zprg;
-EXTERN int dtype;
-EXTERN char* paramspace;
-EXTERN Sym* adrgotype; // type symbol on last Adr read
-EXTERN Sym* fromgotype; // type symbol on last p->from read
EXTERN vlong textstksiz;
EXTERN vlong textarg;
-extern Optab optab[];
-extern Optab* opindex[];
-extern char* anames[];
-
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Iconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Sconv(Fmt*);
-void addhist(int32, int);
-void addstackmark(void);
-Prog* appendp(Prog*);
+int Iconv(Fmt *fp);
+void adddynlib(char *lib);
+void adddynrel(LSym *s, Reloc *r);
+void adddynrela(LSym *rela, LSym *s, Reloc *r);
+void adddynsym(Link *ctxt, LSym *s);
+int archreloc(Reloc *r, LSym *s, vlong *val);
void asmb(void);
-void asmdyn(void);
-void asmins(Prog*);
-void asmsym(void);
-void asmelfsym(void);
-vlong atolwhex(char*);
-Prog* brchain(Prog*);
-Prog* brloop(Prog*);
-void buildop(void);
-Prog* copyp(Prog*);
-double cputime(void);
-void datblk(int32, int32);
-void deadcode(void);
-void diag(char*, ...);
-void dodata(void);
-void doelf(void);
-void domacho(void);
-void doprof1(void);
-void doprof2(void);
-void dostkoff(void);
-vlong entryvalue(void);
-void follow(void);
-void gethunk(void);
-void gotypestrings(void);
+int elfreloc1(Reloc *r, vlong sectoff);
+void elfsetupplt(void);
void listinit(void);
-Sym* lookup(char*, int);
-void lputb(int32);
-void lputl(int32);
-void instinit(void);
-void main(int, char*[]);
-void* mysbrk(uint32);
-Prog* newtext(Prog*, Sym*);
-void nopout(Prog*);
-int opsize(Prog*);
-void patch(void);
-Prog* prg(void);
-void parsetextconst(vlong);
-int relinv(int);
-vlong rnd(vlong, vlong);
-void span(void);
-void undef(void);
-vlong symaddr(Sym*);
-void vputb(uint64);
-void vputl(uint64);
-void wputb(uint16);
-void wputl(uint16);
-void xdefine(char*, int, vlong);
-
-void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32);
-void machsymseg(uint32, uint32);
-void machsect(char*, char*, vlong, vlong, uint32, uint32, uint32, uint32, uint32);
-void machstack(vlong);
-void machdylink(void);
-uint32 machheadr(void);
+int machoreloc1(Reloc *r, vlong sectoff);
+void main(int argc, char *argv[]);
+void parsetextconst(vlong arg);
+vlong rnd(vlong v, vlong r);
/* Native is little-endian */
#define LPUT(a) lputl(a)
#define WPUT(a) wputl(a)
#define VPUT(a) vputl(a)
-#pragma varargck type "D" Adr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "Z" char*
-#pragma varargck type "A" int
-#pragma varargck argpos diag 1
-
/* Used by ../ld/dwarf.c */
enum
{
diff --git a/src/cmd/6l/list.c b/src/cmd/6l/list.c
index 5040e4327..d960fcc91 100644
--- a/src/cmd/6l/list.c
+++ b/src/cmd/6l/list.c
@@ -33,371 +33,14 @@
#include "l.h"
#include "../ld/lib.h"
-static Prog* bigP;
-
void
listinit(void)
{
-
- fmtinstall('R', Rconv);
- fmtinstall('A', Aconv);
- fmtinstall('D', Dconv);
- fmtinstall('S', Sconv);
- fmtinstall('P', Pconv);
+ listinit6();
fmtinstall('I', Iconv);
}
int
-Pconv(Fmt *fp)
-{
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- bigP = p;
- switch(p->as) {
- case ATEXT:
- if(p->from.scale) {
- fmtprint(fp, "(%d) %A %D,%d,%lD",
- p->line, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- fmtprint(fp, "(%d) %A %D,%lD",
- p->line, p->as, &p->from, &p->to);
- break;
- default:
- fmtprint(fp, "(%d) %A %D,%D",
- p->line, p->as, &p->from, &p->to);
- break;
- case ADATA:
- case AINIT_:
- case ADYNT_:
- fmtprint(fp, "(%d) %A %D/%d,%D",
- p->line, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- bigP = P;
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Adr *a;
- int i;
-
- a = va_arg(fp->args, Adr*);
- i = a->type;
-
- if(fp->flags & FmtLong) {
- if(i != D_CONST) {
- // ATEXT dst is not constant
- snprint(str, sizeof(str), "!!%D", a);
- goto brk;
- }
- parsetextconst(a->offset);
- if(textarg == 0) {
- snprint(str, sizeof(str), "$%lld", textstksiz);
- goto brk;
- }
- snprint(str, sizeof(str), "$%lld-%lld", textstksiz, textarg);
- goto brk;
- }
-
- if(i >= D_INDIR) {
- if(a->offset)
- snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof(str), "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- if(a->offset)
- snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
- else
- snprint(str, sizeof(str), "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(bigP != P && bigP->pcond != P)
- if(a->sym != S)
- snprint(str, sizeof(str), "%llux+%s", bigP->pcond->pc,
- a->sym->name);
- else
- snprint(str, sizeof(str), "%llux", bigP->pcond->pc);
- else
- snprint(str, sizeof(str), "%lld(PC)", a->offset);
- break;
-
- case D_EXTERN:
- if(a->sym) {
- snprint(str, sizeof(str), "%s+%lld(SB)", a->sym->name, a->offset);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!+%lld(SB)", a->offset);
- break;
-
- case D_STATIC:
- if(a->sym) {
- snprint(str, sizeof(str), "%s<%d>+%lld(SB)", a->sym->name,
- a->sym->version, a->offset);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!<999>+%lld(SB)", a->offset);
- break;
-
- case D_AUTO:
- if(a->sym) {
- snprint(str, sizeof(str), "%s+%lld(SP)", a->sym->name, a->offset);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!+%lld(SP)", a->offset);
- break;
-
- case D_PARAM:
- if(a->sym) {
- snprint(str, sizeof(str), "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!+%lld(%s)", a->offset, paramspace);
- break;
-
- case D_CONST:
- snprint(str, sizeof(str), "$%lld", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.8ux,%.8ux)", a->ieee.h, a->ieee.l);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%S\"", a->scon);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof(str), "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
-// if(a->gotype)
-// fmtprint(fp, "«%s»", a->gotype->name);
- return 0;
-
-}
-
-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",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_AL && r <= D_NONE)
- snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
- else
- snprint(str, sizeof(str), "gok(%d)", r);
-
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(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);
-}
-
-int
Iconv(Fmt *fp)
{
int i, n;
@@ -422,40 +65,3 @@ Iconv(Fmt *fp)
free(s);
return 0;
}
-
-void
-diag(char *fmt, ...)
-{
- char buf[1024], *tn, *sep;
- va_list arg;
-
- tn = "";
- sep = "";
- if(cursym != S) {
- tn = cursym->name;
- sep = ": ";
- }
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- print("%s%s%s\n", tn, sep, buf);
-
- nerrors++;
- if(nerrors > 20) {
- print("too many errors\n");
- errorexit();
- }
-}
-
-void
-parsetextconst(vlong arg)
-{
- textstksiz = arg & 0xffffffffLL;
- if(textstksiz & 0x80000000LL)
- textstksiz = -(-textstksiz & 0xffffffffLL);
-
- textarg = (arg >> 32) & 0xffffffffLL;
- if(textarg & 0x80000000LL)
- textarg = 0;
- textarg = (textarg+7) & ~7LL;
-}
diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c
index ae649a74b..3b8e8f4d7 100644
--- a/src/cmd/6l/obj.c
+++ b/src/cmd/6l/obj.c
@@ -30,7 +30,6 @@
// Reading object files.
-#define EXTERN
#include "l.h"
#include "../ld/lib.h"
#include "../ld/elf.h"
@@ -39,104 +38,22 @@
#include "../ld/pe.h"
#include <ar.h>
-char *noname = "<none>";
char* thestring = "amd64";
-char* paramspace = "FP";
-
-Header headers[] = {
- "plan9x32", Hplan9x32,
- "plan9", Hplan9x64,
- "elf", Helf,
- "darwin", Hdarwin,
- "dragonfly", Hdragonfly,
- "linux", Hlinux,
- "freebsd", Hfreebsd,
- "netbsd", Hnetbsd,
- "openbsd", Hopenbsd,
- "windows", Hwindows,
- "windowsgui", Hwindows,
- 0, 0
-};
-
-/*
- * -Hplan9x32 -T4128 -R4096 is plan9 32-bit format
- * -Hplan9 -T0x200028 -R0x200000 is plan9 64-bit format
- * -Helf -T0x80110000 -R4096 is ELF32
- * -Hdarwin -Tx -Rx is apple MH-exec
- * -Hdragonfly -Tx -Rx is DragonFly elf-exec
- * -Hlinux -Tx -Rx is linux elf-exec
- * -Hfreebsd -Tx -Rx is FreeBSD elf-exec
- * -Hnetbsd -Tx -Rx is NetBSD elf-exec
- * -Hopenbsd -Tx -Rx is OpenBSD elf-exec
- * -Hwindows -Tx -Rx is MS Windows PE32+
- */
+LinkArch* thelinkarch = &linkamd64;
void
-main(int argc, char *argv[])
+linkarchinit(void)
{
- Binit(&bso, 1, OWRITE);
- listinit();
- memset(debug, 0, sizeof(debug));
- nerrors = 0;
- outfile = nil;
- HEADTYPE = -1;
- INITTEXT = -1;
- INITDAT = -1;
- INITRND = -1;
- INITENTRY = 0;
- linkmode = LinkAuto;
- nuxiinit();
-
- flagcount("1", "use alternate profiling code", &debug['1']);
- flagcount("8", "assume 64-bit addresses", &debug['8']);
- flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
- flagint64("D", "addr: data address", &INITDAT);
- flagstr("E", "sym: entry symbol", &INITENTRY);
- flagfn1("I", "interp: set ELF interp", setinterp);
- flagfn1("L", "dir: add dir to library path", Lflag);
- flagfn1("H", "head: header type", setheadtype);
- flagcount("K", "add stack underflow checks", &debug['K']);
- flagcount("O", "print pc-line tables", &debug['O']);
- flagcount("Q", "debug byte-register code gen", &debug['Q']);
- flagint32("R", "rnd: address rounding", &INITRND);
- flagcount("S", "check type signatures", &debug['S']);
- flagint64("T", "addr: text address", &INITTEXT);
- flagfn0("V", "print version and exit", doversion);
- flagcount("W", "disassemble input", &debug['W']);
- flagfn2("X", "name value: define string data", addstrdata);
- flagcount("Z", "clear stack frame on entry", &debug['Z']);
- flagcount("a", "disassemble output", &debug['a']);
- flagcount("c", "dump call graph", &debug['c']);
- flagcount("d", "disable dynamic executable", &debug['d']);
- flagstr("extld", "linker to run in external mode", &extld);
- flagstr("extldflags", "flags for external linker", &extldflags);
- flagcount("f", "ignore version mismatch", &debug['f']);
- flagcount("g", "disable go package data checks", &debug['g']);
- flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
- flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
- flagstr("k", "sym: set field tracking symbol", &tracksym);
- flagcount("n", "dump symbol table", &debug['n']);
- flagstr("o", "outfile: set output file", &outfile);
- flagcount("p", "insert profiling code", &debug['p']);
- flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
- flagcount("race", "enable race detector", &flag_race);
- flagcount("s", "disable symbol table", &debug['s']);
- flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
- flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
- flagcount("u", "reject unsafe packages", &debug['u']);
- flagcount("v", "print link trace", &debug['v']);
- flagcount("w", "disable DWARF generation", &debug['w']);
-
- flagparse(&argc, &argv, usage);
-
- if(argc != 1)
- usage();
-
- mywhatsys(); // get goos
-
- if(HEADTYPE == -1)
- HEADTYPE = headtype(goos);
+ if(strcmp(getgoarch(), "amd64p32") == 0)
+ thelinkarch = &linkamd64p32;
+ PtrSize = thelinkarch->ptrsize;
+ IntSize = PtrSize;
+ RegSize = thelinkarch->regsize;
+}
+void
+archinit(void)
+{
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash.
if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
@@ -156,34 +73,18 @@ main(int argc, char *argv[])
case Hdragonfly:
case Hfreebsd:
case Hlinux:
+ case Hnacl:
case Hnetbsd:
case Hopenbsd:
+ case Hsolaris:
break;
}
- if(outfile == nil) {
- if(HEADTYPE == Hwindows)
- outfile = "6.out.exe";
- else
- outfile = "6.out";
- }
-
- libinit();
-
switch(HEADTYPE) {
default:
diag("unknown -H option");
errorexit();
- case Hplan9x32: /* plan 9 */
- HEADR = 32L;
- if(INITTEXT == -1)
- INITTEXT = 4096+HEADR;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 4096;
- break;
- case Hplan9x64: /* plan 9 */
+ case Hplan9: /* plan 9 */
HEADR = 32L + 8L;
if(INITTEXT == -1)
INITTEXT = 0x200000+HEADR;
@@ -202,11 +103,6 @@ main(int argc, char *argv[])
INITRND = 4096;
break;
case Hdarwin: /* apple MACH */
- /*
- * OS X system constant - offset from 0(GS) to our TLS.
- * Explained in ../../pkg/runtime/cgo/gcc_darwin_amd64.c.
- */
- tlsoffset = 0x8a0;
machoinit();
HEADR = INITIAL_MACHO_HEADR;
if(INITRND == -1)
@@ -221,13 +117,7 @@ main(int argc, char *argv[])
case Hnetbsd: /* netbsd */
case Hopenbsd: /* openbsd */
case Hdragonfly: /* dragonfly */
- /*
- * ELF uses TLS offset negative from FS.
- * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).
- * Also known to ../../pkg/runtime/sys_linux_amd64.s
- * and ../../pkg/runtime/cgo/gcc_linux_amd64.c.
- */
- tlsoffset = -16;
+ case Hsolaris: /* solaris */
elfinit();
HEADR = ELFRESERVE;
if(INITTEXT == -1)
@@ -237,6 +127,18 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
+ case Hnacl:
+ elfinit();
+ debug['w']++; // disable dwarf, which gets confused and is useless anyway
+ HEADR = 0x10000;
+ funcalign = 32;
+ if(INITTEXT == -1)
+ INITTEXT = 0x20000;
+ if(INITDAT == -1)
+ INITDAT = 0;
+ if(INITRND == -1)
+ INITRND = 0x10000;
+ break;
case Hwindows: /* PE executable */
peinit();
HEADR = PEFILEHEADR;
@@ -248,555 +150,8 @@ main(int argc, char *argv[])
INITRND = PESECTALIGN;
break;
}
+
if(INITDAT != 0 && INITRND != 0)
print("warning: -D0x%llux is ignored because of -R0x%ux\n",
INITDAT, INITRND);
- if(debug['v'])
- Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n",
- HEADTYPE, INITTEXT, INITDAT, INITRND);
- Bflush(&bso);
- instinit();
-
- zprg.link = P;
- zprg.pcond = P;
- zprg.back = 2;
- zprg.as = AGOK;
- zprg.from.type = D_NONE;
- zprg.from.index = D_NONE;
- zprg.from.scale = 1;
- zprg.to = zprg.from;
- zprg.mode = 64;
-
- pcstr = "%.6llux ";
- histgen = 0;
- pc = 0;
- dtype = 4;
- version = 0;
- cbp = buf.cbuf;
- cbc = sizeof(buf.cbuf);
-
- addlibpath("command line", "command line", argv[0], "main");
- loadlib();
- deadcode();
- patch();
- follow();
- doelf();
- if(HEADTYPE == Hdarwin)
- domacho();
- dostkoff();
- dostkcheck();
- paramspace = "SP"; /* (FP) now (SP) on output */
- if(debug['p'])
- if(debug['1'])
- doprof1();
- else
- doprof2();
- span();
- if(HEADTYPE == Hwindows)
- dope();
- addexport();
- textaddress();
- pclntab();
- symtab();
- dodata();
- address();
- doweak();
- reloc();
- asmb();
- undef();
- hostlink();
- if(debug['v']) {
- Bprint(&bso, "%5.2f cpu time\n", cputime());
- Bprint(&bso, "%d symbols\n", nsymbol);
- Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
- Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
- }
- Bflush(&bso);
-
- errorexit();
-}
-
-static Sym*
-zsym(char *pn, Biobuf *f, Sym *h[])
-{
- int o;
-
- o = BGETC(f);
- if(o < 0 || o >= NSYM || h[o] == nil)
- mangle(pn);
- return h[o];
-}
-
-static void
-zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[])
-{
- int t;
- int32 l;
- Sym *s;
- Auto *u;
-
- t = BGETC(f);
- a->index = D_NONE;
- a->scale = 0;
- if(t & T_INDEX) {
- a->index = BGETC(f);
- a->scale = BGETC(f);
- }
- a->offset = 0;
- if(t & T_OFFSET) {
- a->offset = BGETLE4(f);
- if(t & T_64) {
- a->offset &= 0xFFFFFFFFULL;
- a->offset |= (uvlong)BGETLE4(f) << 32;
- }
- }
- a->sym = S;
- if(t & T_SYM)
- a->sym = zsym(pn, f, h);
- a->type = D_NONE;
- if(t & T_FCONST) {
- a->ieee.l = BGETLE4(f);
- a->ieee.h = BGETLE4(f);
- a->type = D_FCONST;
- } else
- if(t & T_SCONST) {
- Bread(f, a->scon, NSNAME);
- a->type = D_SCONST;
- }
- if(t & T_TYPE)
- a->type = BGETC(f);
- if(a->type < 0 || a->type >= D_SIZE)
- mangle(pn);
- adrgotype = S;
- if(t & T_GOTYPE)
- adrgotype = zsym(pn, f, h);
- s = a->sym;
- t = a->type;
- if(t == D_INDIR+D_GS || a->index == D_GS)
- a->offset += tlsoffset;
- if(t != D_AUTO && t != D_PARAM) {
- if(s && adrgotype)
- s->gotype = adrgotype;
- return;
- }
- l = a->offset;
- for(u=curauto; u; u=u->link) {
- if(u->asym == s)
- if(u->type == t) {
- if(u->aoffset > l)
- u->aoffset = l;
- if(adrgotype)
- u->gotype = adrgotype;
- return;
- }
- }
-
- switch(t) {
- case D_FILE:
- case D_FILE1:
- case D_AUTO:
- case D_PARAM:
- if(s == S)
- mangle(pn);
- }
-
- u = mal(sizeof(*u));
- u->link = curauto;
- curauto = u;
- u->asym = s;
- u->aoffset = l;
- u->type = t;
- u->gotype = adrgotype;
-}
-
-void
-nopout(Prog *p)
-{
- p->as = ANOP;
- p->from.type = D_NONE;
- p->to.type = D_NONE;
-}
-
-void
-ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
-{
- vlong ipc;
- Prog *p;
- int v, o, r, skip, mode;
- Sym *h[NSYM], *s;
- uint32 sig;
- char *name, *x;
- int ntext;
- vlong eof;
- char src[1024];
- Prog *lastp;
-
- lastp = nil;
- ntext = 0;
- eof = Boffset(f) + len;
- src[0] = 0;
- pn = estrdup(pn); // we keep it in Sym* references
-
-newloop:
- memset(h, 0, sizeof(h));
- version++;
- histfrogp = 0;
- ipc = pc;
- skip = 0;
- mode = 64;
-
-loop:
- if(f->state == Bracteof || Boffset(f) >= eof)
- goto eof;
- o = BGETC(f);
- if(o == Beof)
- goto eof;
- o |= BGETC(f) << 8;
- if(o <= AXXX || o >= ALAST) {
- if(o < 0)
- goto eof;
- diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
- print(" probably not a .6 file\n");
- errorexit();
- }
-
- if(o == ANAME || o == ASIGNAME) {
- sig = 0;
- if(o == ASIGNAME)
- sig = BGETLE4(f);
- v = BGETC(f); /* type */
- o = BGETC(f); /* sym */
- r = 0;
- if(v == D_STATIC)
- r = version;
- name = Brdline(f, '\0');
- if(name == nil) {
- if(Blinelen(f) > 0) {
- fprint(2, "%s: name too long\n", pn);
- errorexit();
- }
- goto eof;
- }
- x = expandpkg(name, pkg);
- s = lookup(x, r);
- if(x != name)
- free(x);
-
- if(debug['S'] && r == 0)
- sig = 1729;
- if(sig != 0){
- if(s->sig != 0 && s->sig != sig)
- diag("incompatible type signatures "
- "%ux(%s) and %ux(%s) for %s",
- s->sig, s->file, sig, pn, s->name);
- s->sig = sig;
- s->file = pn;
- }
-
- if(debug['W'])
- print(" ANAME %s\n", s->name);
- if(o < 0 || o >= nelem(h))
- mangle(pn);
- h[o] = s;
- if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
- s->type = SXREF;
- if(v == D_FILE) {
- if(s->type != SFILE) {
- histgen++;
- s->type = SFILE;
- s->value = histgen;
- }
- if(histfrogp < MAXHIST) {
- histfrog[histfrogp] = s;
- histfrogp++;
- } else
- collapsefrog(s);
- dwarfaddfrag(s->value, s->name);
- }
- goto loop;
- }
-
- p = mal(sizeof(*p));
- p->as = o;
- p->line = BGETLE4(f);
- p->back = 2;
- p->mode = mode;
- zaddr(pn, f, &p->from, h);
- fromgotype = adrgotype;
- zaddr(pn, f, &p->to, h);
-
- switch(p->as) {
- case ATEXT:
- case ADATA:
- case AGLOBL:
- if(p->from.sym == S)
- mangle(pn);
- break;
- }
-
- if(debug['W'])
- print("%P\n", p);
-
- switch(p->as) {
- case AHISTORY:
- if(p->to.offset == -1) {
- addlib(src, pn);
- histfrogp = 0;
- goto loop;
- }
- if(src[0] == '\0')
- copyhistfrog(src, sizeof src);
- addhist(p->line, D_FILE); /* 'z' */
- if(p->to.offset)
- addhist(p->to.offset, D_FILE1); /* 'Z' */
- savehist(p->line, p->to.offset);
- histfrogp = 0;
- goto loop;
-
- case AEND:
- histtoauto();
- if(cursym != nil && cursym->text)
- cursym->autom = curauto;
- curauto = 0;
- cursym = nil;
- if(Boffset(f) == eof)
- return;
- goto newloop;
-
- case AGLOBL:
- s = p->from.sym;
- if(s->type == 0 || s->type == SXREF) {
- s->type = SBSS;
- s->size = 0;
- }
- if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
- diag("%s: redefinition: %s in %s",
- pn, s->name, TNAME);
- s->type = SBSS;
- s->size = 0;
- }
- if(p->to.offset > s->size)
- s->size = p->to.offset;
- if(p->from.scale & DUPOK)
- s->dupok = 1;
- if(p->from.scale & RODATA)
- s->type = SRODATA;
- else if(p->from.scale & NOPTR)
- s->type = SNOPTRBSS;
- goto loop;
-
- case ADATA:
- // Assume that AGLOBL comes after ADATA.
- // If we've seen an AGLOBL that said this sym was DUPOK,
- // ignore any more ADATA we see, which must be
- // redefinitions.
- s = p->from.sym;
- if(s->dupok) {
-// if(debug['v'])
-// Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
- goto loop;
- }
- if(s->file == nil)
- s->file = pn;
- else if(s->file != pn) {
- diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
- errorexit();
- }
- savedata(s, p, pn);
- unmal(p, sizeof *p);
- goto loop;
-
- case AGOK:
- diag("%s: GOK opcode in %s", pn, TNAME);
- pc++;
- goto loop;
-
- case ATYPE:
- if(skip)
- goto casdef;
- pc++;
- goto loop;
-
- case ATEXT:
- s = p->from.sym;
- if(s->text != nil) {
- if(p->from.scale & DUPOK) {
- skip = 1;
- goto casdef;
- }
- diag("%s: %s: redefinition", pn, s->name);
- return;
- }
- if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
- /* redefinition, so file has probably been seen before */
- if(debug['v'])
- Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name);
- return;
- }
- if(cursym != nil && cursym->text) {
- histtoauto();
- cursym->autom = curauto;
- curauto = 0;
- }
- skip = 0;
- if(etextp)
- etextp->next = s;
- else
- textp = s;
- etextp = s;
- s->text = p;
- cursym = s;
- if(s->type != 0 && s->type != SXREF) {
- if(p->from.scale & DUPOK) {
- skip = 1;
- goto casdef;
- }
- diag("%s: redefinition: %s\n%P", pn, s->name, p);
- }
- if(fromgotype) {
- if(s->gotype && s->gotype != fromgotype)
- diag("%s: type mismatch for %s", pn, s->name);
- s->gotype = fromgotype;
- }
- s->type = STEXT;
- s->hist = gethist();
- s->value = pc;
- s->args = p->to.offset >> 32;
- lastp = p;
- p->pc = pc++;
- goto loop;
-
- case AMODE:
- if(p->from.type == D_CONST || p->from.type == D_INDIR+D_NONE){
- switch((int)p->from.offset){
- case 16: case 32: case 64:
- mode = p->from.offset;
- break;
- }
- }
- goto loop;
-
- case AFMOVF:
- case AFADDF:
- case AFSUBF:
- case AFSUBRF:
- case AFMULF:
- case AFDIVF:
- case AFDIVRF:
- case AFCOMF:
- case AFCOMFP:
- case AMOVSS:
- case AADDSS:
- case ASUBSS:
- case AMULSS:
- case ADIVSS:
- case ACOMISS:
- case AUCOMISS:
- if(skip)
- goto casdef;
- if(p->from.type == D_FCONST) {
- /* size sb 9 max */
- sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
- s = lookup(literal, 0);
- if(s->type == 0) {
- s->type = SRODATA;
- adduint32(s, ieeedtof(&p->from.ieee));
- s->reachable = 0;
- }
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->from.offset = 0;
- }
- goto casdef;
-
- case AFMOVD:
- case AFADDD:
- case AFSUBD:
- case AFSUBRD:
- case AFMULD:
- case AFDIVD:
- case AFDIVRD:
- case AFCOMD:
- case AFCOMDP:
- case AMOVSD:
- case AADDSD:
- case ASUBSD:
- case AMULSD:
- case ADIVSD:
- case ACOMISD:
- case AUCOMISD:
- if(skip)
- goto casdef;
- if(p->from.type == D_FCONST) {
- /* size sb 18 max */
- sprint(literal, "$%ux.%ux",
- p->from.ieee.l, p->from.ieee.h);
- s = lookup(literal, 0);
- if(s->type == 0) {
- s->type = SRODATA;
- adduint32(s, p->from.ieee.l);
- adduint32(s, p->from.ieee.h);
- s->reachable = 0;
- }
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->from.offset = 0;
- }
- goto casdef;
-
- casdef:
- default:
- if(skip)
- nopout(p);
- p->pc = pc;
- pc++;
-
- if(p->to.type == D_BRANCH)
- p->to.offset += ipc;
- if(lastp == nil) {
- if(p->as != ANOP)
- diag("unexpected instruction: %P", p);
- goto loop;
- }
- lastp->link = p;
- lastp = p;
- goto loop;
- }
-
-eof:
- diag("truncated object file: %s", pn);
-}
-
-Prog*
-prg(void)
-{
- Prog *p;
-
- p = mal(sizeof(*p));
-
- *p = zprg;
- return p;
-}
-
-Prog*
-copyp(Prog *q)
-{
- Prog *p;
-
- p = prg();
- *p = *q;
- return p;
-}
-
-Prog*
-appendp(Prog *q)
-{
- Prog *p;
-
- p = prg();
- p->link = q->link;
- q->link = p;
- p->line = q->line;
- p->mode = q->mode;
- return p;
}
diff --git a/src/cmd/6l/optab.c b/src/cmd/6l/optab.c
deleted file mode 100644
index 46603ad45..000000000
--- a/src/cmd/6l/optab.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-// Inferno utils/6l/optab.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/optab.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 "l.h"
-
-uchar ynone[] =
-{
- Ynone, Ynone, Zlit, 1,
- 0
-};
-uchar ytext[] =
-{
- Ymb, Yi64, Zpseudo,1,
- 0
-};
-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
-};
-uchar yfuncdata[] =
-{
- Yi32, Ym, Zpseudo, 0,
- 0
-};
-uchar ypcdata[] =
-{
- Yi32, Yi32, Zpseudo, 0,
- 0
-};
-uchar yxorb[] =
-{
- Yi32, Yal, Zib_, 1,
- Yi32, Ymb, Zibo_m, 2,
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- 0
-};
-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
-};
-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
-};
-uchar yincb[] =
-{
- Ynone, Ymb, Zo_m, 2,
- 0
-};
-uchar yincw[] =
-{
- Ynone, Yml, Zo_m, 2,
- 0
-};
-uchar yincl[] =
-{
- Ynone, Yml, Zo_m, 2,
- 0
-};
-uchar ycmpb[] =
-{
- Yal, Yi32, Z_ib, 1,
- Ymb, Yi32, Zm_ibo, 2,
- Ymb, Yrb, Zm_r, 1,
- Yrb, Ymb, Zr_m, 1,
- 0
-};
-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
-};
-uchar yshb[] =
-{
- Yi1, Ymb, Zo_m, 2,
- Yi32, Ymb, Zibo_m, 2,
- Ycx, Ymb, Zo_m, 2,
- 0
-};
-uchar yshl[] =
-{
- Yi1, Yml, Zo_m, 2,
- Yi32, Yml, Zibo_m, 2,
- Ycl, Yml, Zo_m, 2,
- Ycx, Yml, Zo_m, 2,
- 0
-};
-uchar ytestb[] =
-{
- Yi32, Yal, Zib_, 1,
- Yi32, Ymb, Zibo_m, 2,
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- 0
-};
-uchar ytestl[] =
-{
- Yi32, Yax, Zil_, 1,
- Yi32, Yml, Zilo_m, 2,
- Yrl, Yml, Zr_m, 1,
- Yml, Yrl, Zm_r, 1,
- 0
-};
-uchar ymovb[] =
-{
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- Yi32, Yrb, Zib_rp, 1,
- Yi32, Ymb, Zibo_m, 2,
- 0
-};
-uchar ymbs[] =
-{
- Ymb, Ynone, Zm_o, 2,
- 0
-};
-uchar ybtl[] =
-{
- Yi8, Yml, Zibo_m, 2,
- Yrl, Yml, Zr_m, 1,
- 0
-};
-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
-};
-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
-};
-uchar yret[] =
-{
- Ynone, Ynone, Zo_iw, 1,
- Yi32, Ynone, Zo_iw, 1,
- 0
-};
-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
-};
-uchar ym_rl[] =
-{
- Ym, Yrl, Zm_r, 1,
- 0
-};
-uchar yrl_m[] =
-{
- Yrl, Ym, Zr_m, 1,
- 0
-};
-uchar ymb_rl[] =
-{
- Ymb, Yrl, Zmb_r, 1,
- 0
-};
-uchar yml_rl[] =
-{
- Yml, Yrl, Zm_r, 1,
- 0
-};
-uchar yrl_ml[] =
-{
- Yrl, Yml, Zr_m, 1,
- 0
-};
-uchar yml_mb[] =
-{
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- 0
-};
-uchar yrb_mb[] =
-{
- Yrb, Ymb, Zr_m, 1,
- 0
-};
-uchar yxchg[] =
-{
- Yax, Yrl, Z_rp, 1,
- Yrl, Yax, Zrp_, 1,
- Yrl, Yml, Zr_m, 1,
- Yml, Yrl, Zm_r, 1,
- 0
-};
-uchar ydivl[] =
-{
- Yml, Ynone, Zm_o, 2,
- 0
-};
-uchar ydivb[] =
-{
- Ymb, Ynone, Zm_o, 2,
- 0
-};
-uchar yimul[] =
-{
- Yml, Ynone, Zm_o, 2,
- Yi8, Yrl, Zib_rr, 1,
- Yi32, Yrl, Zil_rr, 1,
- Yml, Yrl, Zm_r, 2,
- 0
-};
-uchar yimul3[] =
-{
- Yml, Yrl, Zibm_r, 2,
- 0
-};
-uchar ybyte[] =
-{
- Yi64, Ynone, Zbyte, 1,
- 0
-};
-uchar yin[] =
-{
- Yi32, Ynone, Zib_, 1,
- Ynone, Ynone, Zlit, 1,
- 0
-};
-uchar yint[] =
-{
- Yi32, Ynone, Zib_, 1,
- 0
-};
-uchar ypushl[] =
-{
- Yrl, Ynone, Zrp_, 1,
- Ym, Ynone, Zm_o, 2,
- Yi8, Ynone, Zib_, 1,
- Yi32, Ynone, Zil_, 1,
- 0
-};
-uchar ypopl[] =
-{
- Ynone, Yrl, Z_rp, 1,
- Ynone, Ym, Zo_m, 2,
- 0
-};
-uchar ybswap[] =
-{
- Ynone, Yrl, Z_rp, 2,
- 0,
-};
-uchar yscond[] =
-{
- Ynone, Ymb, Zo_m, 2,
- 0
-};
-uchar yjcond[] =
-{
- Ynone, Ybr, Zbr, 0,
- Yi0, Ybr, Zbr, 0,
- Yi1, Ybr, Zbr, 1,
- 0
-};
-uchar yloop[] =
-{
- Ynone, Ybr, Zloop, 1,
- 0
-};
-uchar ycall[] =
-{
- Ynone, Yml, Zo_m64, 0,
- Yrx, Yrx, Zo_m64, 2,
- Ynone, Ybr, Zcall, 1,
- 0
-};
-uchar yjmp[] =
-{
- Ynone, Yml, Zo_m64, 2,
- Ynone, Ybr, Zjmp, 1,
- 0
-};
-
-uchar yfmvd[] =
-{
- Ym, Yf0, Zm_o, 2,
- Yf0, Ym, Zo_m, 2,
- Yrf, Yf0, Zm_o, 2,
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfmvdp[] =
-{
- Yf0, Ym, Zo_m, 2,
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfmvf[] =
-{
- Ym, Yf0, Zm_o, 2,
- Yf0, Ym, Zo_m, 2,
- 0
-};
-uchar yfmvx[] =
-{
- Ym, Yf0, Zm_o, 2,
- 0
-};
-uchar yfmvp[] =
-{
- Yf0, Ym, Zo_m, 2,
- 0
-};
-uchar yfadd[] =
-{
- Ym, Yf0, Zm_o, 2,
- Yrf, Yf0, Zm_o, 2,
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfaddp[] =
-{
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfxch[] =
-{
- Yf0, Yrf, Zo_m, 2,
- Yrf, Yf0, Zm_o, 2,
- 0
-};
-uchar ycompp[] =
-{
- Yf0, Yrf, Zo_m, 2, /* botch is really f0,f1 */
- 0
-};
-uchar ystsw[] =
-{
- Ynone, Ym, Zo_m, 2,
- Ynone, Yax, Zlit, 1,
- 0
-};
-uchar ystcw[] =
-{
- Ynone, Ym, Zo_m, 2,
- Ym, Ynone, Zm_o, 2,
- 0
-};
-uchar ysvrs[] =
-{
- Ynone, Ym, Zo_m, 2,
- Ym, Ynone, Zm_o, 2,
- 0
-};
-uchar ymm[] =
-{
- Ymm, Ymr, Zm_r_xm, 1,
- Yxm, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar yxm[] =
-{
- Yxm, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxcvm1[] =
-{
- Yxm, Yxr, Zm_r_xm, 2,
- Yxm, Ymr, Zm_r_xm, 2,
- 0
-};
-uchar yxcvm2[] =
-{
- Yxm, Yxr, Zm_r_xm, 2,
- Ymm, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar yxmq[] =
-{
- Yxm, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar yxr[] =
-{
- Yxr, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxr_ml[] =
-{
- Yxr, Yml, Zr_m_xm, 1,
- 0
-};
-uchar ymr[] =
-{
- Ymr, Ymr, Zm_r, 1,
- 0
-};
-uchar ymr_ml[] =
-{
- Ymr, Yml, Zr_m_xm, 1,
- 0
-};
-uchar yxcmp[] =
-{
- Yxm, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxcmpi[] =
-{
- Yxm, Yxr, Zm_r_i_xm, 2,
- 0
-};
-uchar yxmov[] =
-{
- Yxm, Yxr, Zm_r_xm, 1,
- Yxr, Yxm, Zr_m_xm, 1,
- 0
-};
-uchar yxcvfl[] =
-{
- Yxm, Yrl, Zm_r_xm, 1,
- 0
-};
-uchar yxcvlf[] =
-{
- Yml, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxcvfq[] =
-{
- Yxm, Yrl, Zm_r_xm, 2,
- 0
-};
-uchar yxcvqf[] =
-{
- Yml, Yxr, Zm_r_xm, 2,
- 0
-};
-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
-};
-uchar yxrrl[] =
-{
- Yxr, Yrl, Zm_r, 1,
- 0
-};
-uchar ymfp[] =
-{
- Ymm, Ymr, Zm_r_3d, 1,
- 0,
-};
-uchar ymrxr[] =
-{
- Ymr, Yxr, Zm_r, 1,
- Yxm, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar ymshuf[] =
-{
- Ymm, Ymr, Zibm_r, 2,
- 0
-};
-uchar ymshufb[] =
-{
- Yxm, Yxr, Zm2_r, 2,
- 0
-};
-uchar yxshuf[] =
-{
- Yxm, Yxr, Zibm_r, 2,
- 0
-};
-uchar yextrw[] =
-{
- Yxr, Yrl, Zibm_r, 2,
- 0
-};
-uchar yinsrw[] =
-{
- Yml, Yxr, Zibm_r, 2,
- 0
-};
-uchar yinsr[] =
-{
- Ymm, Yxr, Zibm_r, 3,
- 0
-};
-uchar ypsdq[] =
-{
- Yi8, Yxr, Zibo_m, 2,
- 0
-};
-uchar ymskb[] =
-{
- Yxr, Yrl, Zm_r_xm, 2,
- Ymr, Yrl, Zm_r_xm, 1,
- 0
-};
-uchar ycrc32l[] =
-{
- Yml, Yrl, Zlitm_r, 0,
-};
-uchar yprefetch[] =
-{
- Ym, Ynone, Zm_o, 2,
- 0,
-};
-uchar yaes[] =
-{
- Yxm, Yxr, Zlitm_r, 2,
- 0
-};
-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 (Adr*). 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.
- */
-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 },
- { AGOK },
- { AHISTORY },
- { 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, Pw, 0x0f,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) },
- { ANAME },
- { 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, 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, 0x96,(00) },
- { ASETPL, yscond, Pm, 0x99,(00) },
- { ASETPS, yscond, Pm, 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 },
- { AFUNCDATA, yfuncdata, Px, 0,0 },
- { APCDATA, ypcdata, Px, 0,0 },
-
- { AEND },
- 0
-};
-
-Optab* opindex[ALAST+1];
-
-/*
-AMOVD 0f 6e/r mmx,reg/mem32[mem64-rex?]
-AMOVD 0f 7e/r reg/mem32[64],mmx STORE
-AMOVQ 0f 6f/r mmx1,mmx2/mem64
-AMOVQ 0f 7f/r mmx1/mem64,mmx2
-*/
diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c
deleted file mode 100644
index 1be3c18fe..000000000
--- a/src/cmd/6l/pass.c
+++ /dev/null
@@ -1,991 +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 "l.h"
-#include "../ld/lib.h"
-#include "../../pkg/runtime/stack.h"
-
-static void xfol(Prog*, Prog**);
-
-Prog*
-brchain(Prog *p)
-{
- int i;
-
- for(i=0; i<20; i++) {
- if(p == P || p->as != AJMP)
- return p;
- p = p->pcond;
- }
- return P;
-}
-
-void
-follow(void)
-{
- Prog *firstp, *lastp;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f follow\n", cputime());
- Bflush(&bso);
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- firstp = prg();
- lastp = firstp;
- xfol(cursym->text, &lastp);
- lastp->link = nil;
- cursym->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 void
-xfol(Prog *p, Prog **last)
-{
- Prog *q;
- int i;
- enum as a;
-
-loop:
- if(p == P)
- return;
- if(p->as == AJMP)
- if((q = p->pcond) != P && 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 == P)
- 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 == P || q->pcond->mark)
- continue;
- if(a == ACALL || a == ALOOP)
- continue;
- for(;;) {
- if(p->as == ANOP) {
- p = p->link;
- continue;
- }
- q = copyp(p);
- p = p->link;
- q->mark = 1;
- (*last)->link = q;
- *last = q;
- if(q->as != a || q->pcond == P || q->pcond->mark)
- continue;
-
- q->as = relinv(q->as);
- p = q->pcond;
- q->pcond = q->link;
- q->link = p;
- xfol(q->link, last);
- p = q->link;
- if(p->mark)
- return;
- goto loop;
- }
- } /* */
- q = prg();
- q->as = AJMP;
- q->line = p->line;
- q->to.type = D_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 != P && a != ACALL) {
- /*
- * some kind of conditional branch.
- * recurse to follow one path.
- * continue loop on the other.
- */
- if((q = brchain(p->pcond)) != P)
- p->pcond = q;
- if((q = brchain(p->link)) != P)
- p->link = q;
- if(p->from.type == D_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(p->link, last);
- if(p->pcond->mark)
- return;
- p = p->pcond;
- goto loop;
- }
- p = p->link;
- goto loop;
-}
-
-Prog*
-byteq(int v)
-{
- Prog *p;
-
- p = prg();
- p->as = ABYTE;
- p->from.type = D_CONST;
- p->from.offset = v&0xff;
- return p;
-}
-
-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;
- }
- diag("unknown relation: %s in %s", anames[a], TNAME);
- errorexit();
- return a;
-}
-
-void
-patch(void)
-{
- int32 c;
- Prog *p, *q;
- Sym *s;
- int32 vexit;
- Sym *gmsym;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f mkfwd\n", cputime());
- Bflush(&bso);
- mkfwd();
- if(debug['v'])
- Bprint(&bso, "%5.2f patch\n", cputime());
- Bflush(&bso);
-
- if(flag_shared) {
- s = lookup("init_array", 0);
- s->type = SINITARR;
- s->reachable = 1;
- s->hide = 1;
- addaddr(s, lookup(INITENTRY, 0));
- }
-
- gmsym = lookup("runtime.tlsgm", 0);
- if(linkmode != LinkExternal)
- gmsym->reachable = 0;
- s = lookup("exit", 0);
- vexit = s->value;
- for(cursym = textp; cursym != nil; cursym = cursym->next)
- for(p = cursym->text; p != P; p = p->link) {
- if(HEADTYPE == Hwindows) {
- // Windows
- // Convert
- // op n(GS), reg
- // to
- // MOVL 0x28(GS), reg
- // op n(reg), reg
- // The purpose of this patch is to fix some accesses
- // to extern register variables (TLS) on Windows, as
- // a different method is used to access them.
- if(p->from.type == D_INDIR+D_GS
- && p->to.type >= D_AX && p->to.type <= D_DI
- && p->from.offset <= 8) {
- q = appendp(p);
- q->from = p->from;
- q->from.type = D_INDIR + p->to.type;
- q->to = p->to;
- q->as = p->as;
- p->as = AMOVQ;
- p->from.type = D_INDIR+D_GS;
- p->from.offset = 0x28;
- }
- }
- if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd
- || HEADTYPE == Hopenbsd || HEADTYPE == Hnetbsd
- || HEADTYPE == Hplan9x64 || HEADTYPE == Hdragonfly) {
- // ELF uses FS instead of GS.
- if(p->from.type == D_INDIR+D_GS)
- p->from.type = D_INDIR+D_FS;
- if(p->to.type == D_INDIR+D_GS)
- p->to.type = D_INDIR+D_FS;
- if(p->from.index == D_GS)
- p->from.index = D_FS;
- if(p->to.index == D_GS)
- p->to.index = D_FS;
- }
- if(!flag_shared) {
- // Convert g() or m() accesses of the form
- // op n(reg)(GS*1), reg
- // to
- // op n(GS*1), reg
- if(p->from.index == D_FS || p->from.index == D_GS) {
- p->from.type = D_INDIR + p->from.index;
- p->from.index = D_NONE;
- }
- // Convert g() or m() accesses of the form
- // op reg, n(reg)(GS*1)
- // to
- // op reg, n(GS*1)
- if(p->to.index == D_FS || p->to.index == D_GS) {
- p->to.type = D_INDIR + p->to.index;
- p->to.index = D_NONE;
- }
- // Convert get_tls access of the form
- // op runtime.tlsgm(SB), reg
- // to
- // NOP
- if(gmsym != S && p->from.sym == gmsym) {
- p->as = ANOP;
- p->from.type = D_NONE;
- p->to.type = D_NONE;
- p->from.sym = nil;
- p->to.sym = nil;
- continue;
- }
- } else {
- // Convert TLS reads of the form
- // op n(GS), reg
- // to
- // MOVQ $runtime.tlsgm(SB), reg
- // op n(reg)(GS*1), reg
- if((p->from.type == D_INDIR+D_FS || p->from.type == D_INDIR + D_GS) && p->to.type >= D_AX && p->to.type <= D_DI) {
- q = appendp(p);
- q->to = p->to;
- q->as = p->as;
- q->from.type = D_INDIR+p->to.type;
- q->from.index = p->from.type - D_INDIR;
- q->from.scale = 1;
- q->from.offset = p->from.offset;
- p->as = AMOVQ;
- p->from.type = D_EXTERN;
- p->from.sym = gmsym;
- p->from.offset = 0;
- }
- }
- if(p->as == ACALL || (p->as == AJMP && p->to.type != D_BRANCH) || (p->as == ARET && p->to.sym != nil)) {
- s = p->to.sym;
- if(s) {
- if(debug['c'])
- Bprint(&bso, "%s calls %s\n", TNAME, s->name);
- if((s->type&SMASK) != STEXT) {
- /* diag prints TNAME first */
- diag("undefined: %s", s->name);
- s->type = STEXT;
- s->value = vexit;
- continue; // avoid more error messages
- }
- if(s->text == nil)
- continue;
- p->to.type = D_BRANCH;
- p->to.offset = s->text->pc;
- p->pcond = s->text;
- continue;
- }
- }
- if(p->to.type != D_BRANCH)
- continue;
- c = p->to.offset;
- for(q = cursym->text; q != P;) {
- if(c == q->pc)
- break;
- if(q->forwd != P && c >= q->forwd->pc)
- q = q->forwd;
- else
- q = q->link;
- }
- if(q == P) {
- diag("branch out of range in %s (%#ux)\n%P [%s]",
- TNAME, c, p, p->to.sym ? p->to.sym->name : "<nil>");
- p->to.type = D_NONE;
- }
- p->pcond = q;
- }
-
- for(cursym = textp; cursym != nil; cursym = cursym->next)
- for(p = cursym->text; p != P; p = p->link) {
- p->mark = 0; /* initialization for follow */
- if(p->pcond != P) {
- p->pcond = brloop(p->pcond);
- if(p->pcond != P)
- if(p->to.type == D_BRANCH)
- p->to.offset = p->pcond->pc;
- }
- }
-}
-
-Prog*
-brloop(Prog *p)
-{
- int c;
- Prog *q;
-
- c = 0;
- for(q = p; q != P; q = q->pcond) {
- if(q->as != AJMP)
- break;
- c++;
- if(c >= 5000)
- return P;
- }
- return q;
-}
-
-static char*
-morename[] =
-{
- "runtime.morestack00",
- "runtime.morestack10",
- "runtime.morestack01",
- "runtime.morestack11",
-
- "runtime.morestack8",
- "runtime.morestack16",
- "runtime.morestack24",
- "runtime.morestack32",
- "runtime.morestack40",
- "runtime.morestack48",
-};
-Prog* pmorestack[nelem(morename)];
-Sym* symmorestack[nelem(morename)];
-Sym* gmsym;
-
-static Prog* load_g_cx(Prog*);
-static Prog* stacksplit(Prog*, int32, Prog**);
-
-void
-dostkoff(void)
-{
- Prog *p, *q, *q1;
- int32 autoffset, deltasp;
- int a, pcsize;
- uint32 i;
-
- gmsym = lookup("runtime.tlsgm", 0);
- for(i=0; i<nelem(morename); i++) {
- symmorestack[i] = lookup(morename[i], 0);
- if(symmorestack[i]->type != STEXT)
- diag("morestack trampoline not defined - %s", morename[i]);
- pmorestack[i] = symmorestack[i]->text;
- }
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(cursym->text == nil || cursym->text->link == nil)
- continue;
-
- p = cursym->text;
- parsetextconst(p->to.offset);
- autoffset = textstksiz;
- if(autoffset < 0)
- autoffset = 0;
-
- if(autoffset < StackSmall && !(p->from.scale & NOSPLIT)) {
- for(q = p; q != P; q = q->link)
- if(q->as == ACALL)
- goto noleaf;
- p->from.scale |= NOSPLIT;
- noleaf:;
- }
-
- if((p->from.scale & NOSPLIT) && autoffset >= StackSmall)
- diag("nosplit func likely to overflow stack");
-
- q = P;
- if(!(p->from.scale & NOSPLIT) || (p->from.scale & WRAPPER)) {
- p = appendp(p);
- p = load_g_cx(p); // load g into CX
- }
- if(!(cursym->text->from.scale & NOSPLIT))
- p = stacksplit(p, autoffset, &q); // emit split check
-
- if(autoffset) {
- p = appendp(p);
- p->as = AADJSP;
- p->from.type = D_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(p);
- p->as = ANOP;
- p->spadj = -PtrSize;
- p = appendp(p);
- p->as = ANOP;
- p->spadj = PtrSize;
- }
- if(q != P)
- q->pcond = p;
- deltasp = autoffset;
-
- if(cursym->text->from.scale & WRAPPER) {
- // g->panicwrap += autoffset + PtrSize;
- p = appendp(p);
- p->as = AADDL;
- p->from.type = D_CONST;
- p->from.offset = autoffset + PtrSize;
- p->to.type = D_INDIR+D_CX;
- p->to.offset = 2*PtrSize;
- }
-
- if(debug['K'] > 1 && autoffset) {
- // 6l -KK means double-check for stack overflow
- // even after calling morestack and even if the
- // function is marked as nosplit.
- p = appendp(p);
- p->as = AMOVQ;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 0;
- p->to.type = D_BX;
-
- p = appendp(p);
- p->as = ASUBQ;
- p->from.type = D_CONST;
- p->from.offset = StackSmall+32;
- p->to.type = D_BX;
-
- p = appendp(p);
- p->as = ACMPQ;
- p->from.type = D_SP;
- p->to.type = D_BX;
-
- p = appendp(p);
- p->as = AJHI;
- p->to.type = D_BRANCH;
- q1 = p;
-
- p = appendp(p);
- p->as = AINT;
- p->from.type = D_CONST;
- p->from.offset = 3;
-
- p = appendp(p);
- p->as = ANOP;
- q1->pcond = p;
- }
-
- if(debug['Z'] && autoffset && !(cursym->text->from.scale&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(p);
- p->as = AMOVQ;
- p->from.type = D_SP;
- p->to.type = D_DI;
-
- p = appendp(p);
- p->as = AMOVQ;
- p->from.type = D_CONST;
- p->from.offset = autoffset/8;
- p->to.type = D_CX;
-
- p = appendp(p);
- p->as = AMOVQ;
- p->from.type = D_CONST;
- p->from.offset = 0;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = AREP;
-
- p = appendp(p);
- p->as = ASTOSQ;
- }
-
- for(; p != P; p = p->link) {
- pcsize = p->mode/8;
- a = p->from.type;
- if(a == D_AUTO)
- p->from.offset += deltasp;
- if(a == D_PARAM)
- p->from.offset += deltasp + pcsize;
- a = p->to.type;
- if(a == D_AUTO)
- p->to.offset += deltasp;
- if(a == D_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)
- diag("unbalanced PUSH/POP");
-
- if(cursym->text->from.scale & WRAPPER) {
- p = load_g_cx(p);
- p = appendp(p);
- // g->panicwrap -= autoffset + PtrSize;
- p->as = ASUBL;
- p->from.type = D_CONST;
- p->from.offset = autoffset + PtrSize;
- p->to.type = D_INDIR+D_CX;
- p->to.offset = 2*PtrSize;
- p = appendp(p);
- p->as = ARET;
- }
-
- if(autoffset) {
- p->as = AADJSP;
- p->from.type = D_CONST;
- p->from.offset = -autoffset;
- p->spadj = -autoffset;
- p = appendp(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(Prog *p)
-{
- if(flag_shared) {
- // Load TLS offset with MOVQ $runtime.tlsgm(SB), CX
- p->as = AMOVQ;
- p->from.type = D_EXTERN;
- p->from.sym = gmsym;
- p->to.type = D_CX;
- p = appendp(p);
- }
- p->as = AMOVQ;
- if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd
- || HEADTYPE == Hopenbsd || HEADTYPE == Hnetbsd
- || HEADTYPE == Hplan9x64 || HEADTYPE == Hdragonfly)
- // ELF uses FS
- p->from.type = D_INDIR+D_FS;
- else
- p->from.type = D_INDIR+D_GS;
- if(flag_shared) {
- // Add TLS offset stored in CX
- p->from.index = p->from.type - D_INDIR;
- p->from.type = D_INDIR + D_CX;
- }
- p->from.offset = tlsoffset+0;
- p->to.type = D_CX;
- if(HEADTYPE == Hwindows) {
- // movq %gs:0x28, %rcx
- // movq (%rcx), %rcx
- p->as = AMOVQ;
- p->from.type = D_INDIR+D_GS;
- p->from.offset = 0x28;
- p->to.type = D_CX;
-
- p = appendp(p);
- p->as = AMOVQ;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 0;
- p->to.type = D_CX;
- }
- 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(Prog *p, int32 framesize, Prog **jmpok)
-{
- Prog *q, *q1;
- uint32 moreconst1, moreconst2, i;
-
- if(debug['K']) {
- // 6l -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(p);
- p->as = ACMPQ;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 8;
- p->to.type = D_SP;
-
- p = appendp(p);
- p->as = AJHI;
- p->to.type = D_BRANCH;
- p->to.offset = 4;
- q1 = p;
-
- p = appendp(p);
- p->as = AINT;
- p->from.type = D_CONST;
- p->from.offset = 3;
-
- p = appendp(p);
- p->as = ANOP;
- q1->pcond = p;
- }
-
- q = P;
- q1 = P;
- if(framesize <= StackSmall) {
- // small stack: SP <= stackguard
- // CMPQ SP, stackguard
- p = appendp(p);
- p->as = ACMPQ;
- p->from.type = D_SP;
- p->to.type = D_INDIR+D_CX;
- } else if(framesize <= StackBig) {
- // large stack: SP-framesize <= stackguard-StackSmall
- // LEAQ -xxx(SP), AX
- // CMPQ AX, stackguard
- p = appendp(p);
- p->as = ALEAQ;
- p->from.type = D_INDIR+D_SP;
- p->from.offset = -(framesize-StackSmall);
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACMPQ;
- p->from.type = D_AX;
- p->to.type = D_INDIR+D_CX;
- } 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(p);
- p->as = AMOVQ;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 0;
- p->to.type = D_SI;
-
- p = appendp(p);
- p->as = ACMPQ;
- p->from.type = D_SI;
- p->to.type = D_CONST;
- p->to.offset = StackPreempt;
-
- p = appendp(p);
- p->as = AJEQ;
- p->to.type = D_BRANCH;
- q1 = p;
-
- p = appendp(p);
- p->as = ALEAQ;
- p->from.type = D_INDIR+D_SP;
- p->from.offset = StackGuard;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ASUBQ;
- p->from.type = D_SI;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACMPQ;
- p->from.type = D_AX;
- p->to.type = D_CONST;
- p->to.offset = framesize+(StackGuard-StackSmall);
- }
-
- // common
- p = appendp(p);
- p->as = AJHI;
- p->to.type = D_BRANCH;
- q = p;
-
- // If we ask for more stack, we'll get a minimum of StackMin bytes.
- // We need a stack frame large enough to hold the top-of-stack data,
- // the function arguments+results, our caller's PC, our frame,
- // a word for the return PC of the next call, and then the StackLimit bytes
- // that must be available on entry to any function called from a function
- // that did a stack check. If StackMin is enough, don't ask for a specific
- // amount: then we can use the custom functions and save a few
- // instructions.
- moreconst1 = 0;
- if(StackTop + textarg + PtrSize + framesize + PtrSize + StackLimit >= StackMin)
- moreconst1 = framesize;
- moreconst2 = textarg;
- if(moreconst2 == 1) // special marker
- moreconst2 = 0;
- if((moreconst2&7) != 0)
- diag("misaligned argument size in stack split");
- // 4 varieties varieties (const1==0 cross const2==0)
- // and 6 subvarieties of (const1==0 and const2!=0)
- p = appendp(p);
- if(moreconst1 == 0 && moreconst2 == 0) {
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = pmorestack[0];
- p->to.sym = symmorestack[0];
- } else
- if(moreconst1 != 0 && moreconst2 == 0) {
- p->as = AMOVL;
- p->from.type = D_CONST;
- p->from.offset = moreconst1;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = pmorestack[1];
- p->to.sym = symmorestack[1];
- } else
- if(moreconst1 == 0 && moreconst2 <= 48 && moreconst2%8 == 0) {
- i = moreconst2/8 + 3;
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = pmorestack[i];
- p->to.sym = symmorestack[i];
- } else
- if(moreconst1 == 0 && moreconst2 != 0) {
- p->as = AMOVL;
- p->from.type = D_CONST;
- p->from.offset = moreconst2;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = pmorestack[2];
- p->to.sym = symmorestack[2];
- } else {
- p->as = AMOVQ;
- p->from.type = D_CONST;
- p->from.offset = (uint64)moreconst2 << 32;
- p->from.offset |= moreconst1;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = pmorestack[3];
- p->to.sym = symmorestack[3];
- }
-
- p = appendp(p);
- p->as = AJMP;
- p->to.type = D_BRANCH;
- p->pcond = cursym->text->link;
-
- if(q != P)
- q->pcond = p->link;
- if(q1 != P)
- q1->pcond = q->link;
-
- *jmpok = q;
- return p;
-}
-
-vlong
-atolwhex(char *s)
-{
- vlong n;
- int f;
-
- n = 0;
- f = 0;
- while(*s == ' ' || *s == '\t')
- s++;
- if(*s == '-' || *s == '+') {
- if(*s++ == '-')
- f = 1;
- while(*s == ' ' || *s == '\t')
- s++;
- }
- if(s[0]=='0' && s[1]){
- if(s[1]=='x' || s[1]=='X'){
- s += 2;
- for(;;){
- if(*s >= '0' && *s <= '9')
- n = n*16 + *s++ - '0';
- else if(*s >= 'a' && *s <= 'f')
- n = n*16 + *s++ - 'a' + 10;
- else if(*s >= 'A' && *s <= 'F')
- n = n*16 + *s++ - 'A' + 10;
- else
- break;
- }
- } else
- while(*s >= '0' && *s <= '7')
- n = n*8 + *s++ - '0';
- } else
- while(*s >= '0' && *s <= '9')
- n = n*10 + *s++ - '0';
- if(f)
- n = -n;
- return n;
-}
diff --git a/src/cmd/6l/prof.c b/src/cmd/6l/prof.c
deleted file mode 100644
index 862ce080c..000000000
--- a/src/cmd/6l/prof.c
+++ /dev/null
@@ -1,171 +0,0 @@
-// Inferno utils/6l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.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.
-
-// Profiling.
-
-#include "l.h"
-#include "../ld/lib.h"
-
-void
-doprof1(void)
-{
-#ifdef NOTDEF
- Sym *s;
- int32 n;
- Prog *p, *q;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f profile 1\n", cputime());
- Bflush(&bso);
- s = lookup("__mcount", 0);
- n = 1;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
- q = prg();
- q->line = p->line;
- q->link = datap;
- datap = q;
- q->as = ADATA;
- q->from.type = D_EXTERN;
- q->from.offset = n*4;
- q->from.sym = s;
- q->from.scale = 4;
- q->to = p->from;
- q->to.type = D_CONST;
-
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = AADDL;
- p->from.type = D_CONST;
- p->from.offset = 1;
- p->to.type = D_EXTERN;
- p->to.sym = s;
- p->to.offset = n*4 + 4;
-
- n += 2;
- }
- q = prg();
- q->line = 0;
- q->link = datap;
- datap = q;
-
- q->as = ADATA;
- q->from.type = D_EXTERN;
- q->from.sym = s;
- q->from.scale = 4;
- q->to.type = D_CONST;
- q->to.offset = n;
-
- s->type = SBSS;
- s->size = n*4;
-#endif
-}
-
-void
-doprof2(void)
-{
- Sym *s2, *s4;
- Prog *p, *q, *ps2, *ps4;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f profile 2\n", cputime());
- Bflush(&bso);
-
- s2 = lookup("_profin", 0);
- s4 = lookup("_profout", 0);
- if(s2->type != STEXT || s4->type != STEXT) {
- diag("_profin/_profout not defined");
- return;
- }
-
- ps2 = P;
- ps4 = P;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
- if(p->from.sym == s2) {
- p->from.scale = 1;
- ps2 = p;
- }
- if(p->from.sym == s4) {
- p->from.scale = 1;
- ps4 = p;
- }
- }
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
-
- if(p->from.scale & NOPROF) /* dont profile */
- continue;
-
- /*
- * JMPL profin
- */
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = ps2;
- p->to.sym = s2;
-
- for(; p; p=p->link) {
- if(p->as == ARET) {
- /*
- * RET
- */
- q = prg();
- q->as = ARET;
- q->from = p->from;
- q->to = p->to;
- q->link = p->link;
- p->link = q;
-
- /*
- * JAL profout
- */
- p->as = ACALL;
- p->from = zprg.from;
- p->to = zprg.to;
- p->to.type = D_BRANCH;
- p->pcond = ps4;
- p->to.sym = s4;
-
- p = q;
- }
- }
- }
-}
diff --git a/src/cmd/6l/span.c b/src/cmd/6l/span.c
deleted file mode 100644
index 74f11d635..000000000
--- a/src/cmd/6l/span.c
+++ /dev/null
@@ -1,1846 +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 "l.h"
-#include "../ld/lib.h"
-#include "../ld/elf.h"
-
-static int rexflag;
-static int asmode;
-static vlong vaddr(Adr*, 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},
- {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;
- }
-}
-
-void
-span1(Sym *s)
-{
- Prog *p, *q;
- int32 c, v, loop;
- uchar *bp;
- int n, m, i;
-
- cursym = s;
-
- if(s->p != nil)
- return;
-
- for(p = s->text; p != P; p = p->link) {
- p->back = 2; // use short branches first time through
- if((q = p->pcond) != P && (q->back & 2)) {
- p->back |= 1; // backward jump
- q->back |= 4; // loop head
- }
-
- if(p->as == AADJSP) {
- p->to.type = D_SP;
- v = -p->from.offset;
- p->from.offset = v;
- p->as = p->mode != 64? AADDL: AADDQ;
- if(v < 0) {
- p->as = p->mode != 64? 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 != P; p = p->link) {
- if((p->back & 4) && (c&(LoopAlign-1)) != 0) {
- // pad with NOPs
- v = -c&(LoopAlign-1);
- if(v <= MaxLoopPad) {
- symgrow(s, c+v);
- fillnop(s->p+c, v);
- c += v;
- }
- }
-
- p->pc = c;
-
- // process forward jumps to p
- for(q = p->comefrom; q != P; 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 = P;
-
- asmins(p);
- p->pc = c;
- m = andptr-and;
- symgrow(s, p->pc+m);
- memmove(s->p+p->pc, and, m);
- p->mark = m;
- c += m;
- }
- if(++n > 20) {
- diag("span must be looping");
- errorexit();
- }
- } while(loop);
- s->size = c;
-
- if(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);
- }
- }
-}
-
-void
-span(void)
-{
- Prog *p, *q;
- int32 v;
- int n;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f span\n", cputime());
-
- // NOTE(rsc): If we get rid of the globals we should
- // be able to parallelize these iterations.
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(cursym->p != nil)
- continue;
- // TODO: move into span1
- for(p = cursym->text; p != P; p = p->link) {
- n = 0;
- if(p->to.type == D_BRANCH)
- if(p->pcond == P)
- p->pcond = p;
- if((q = p->pcond) != P)
- if(q->back != 2)
- n = 1;
- p->back = n;
- if(p->as == AADJSP) {
- p->to.type = D_SP;
- v = -p->from.offset;
- p->from.offset = v;
- p->as = p->mode != 64? AADDL: AADDQ;
- if(v < 0) {
- p->as = p->mode != 64? ASUBL: ASUBQ;
- v = -v;
- p->from.offset = v;
- }
- if(v == 0)
- p->as = ANOP;
- }
- }
- span1(cursym);
- }
-}
-
-void
-xdefine(char *p, int t, vlong v)
-{
- Sym *s;
-
- s = lookup(p, 0);
- s->type = t;
- s->value = v;
- s->reachable = 1;
- s->special = 1;
-}
-
-void
-instinit(void)
-{
- int c, i;
-
- for(i=1; optab[i].as; i++) {
- c = optab[i].as;
- if(opindex[c] != nil) {
- diag("phase error in optab: %d (%A)", i, c);
- errorexit();
- }
- 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<D_NONE; i++) {
- reg[i] = -1;
- if(i >= D_AL && i <= D_R15B) {
- reg[i] = (i-D_AL) & 7;
- if(i >= D_SPB && i <= D_DIB)
- regrex[i] = 0x40;
- if(i >= D_R8B && i <= D_R15B)
- regrex[i] = Rxr | Rxx | Rxb;
- }
- if(i >= D_AH && i<= D_BH)
- reg[i] = 4 + ((i-D_AH) & 7);
- if(i >= D_AX && i <= D_R15) {
- reg[i] = (i-D_AX) & 7;
- if(i >= D_R8)
- regrex[i] = Rxr | Rxx | Rxb;
- }
- if(i >= D_F0 && i <= D_F0+7)
- reg[i] = (i-D_F0) & 7;
- if(i >= D_M0 && i <= D_M0+7)
- reg[i] = (i-D_M0) & 7;
- if(i >= D_X0 && i <= D_X0+15) {
- reg[i] = (i-D_X0) & 7;
- if(i >= D_X0+8)
- regrex[i] = Rxr | Rxx | Rxb;
- }
- if(i >= D_CR+8 && i <= D_CR+15)
- regrex[i] = Rxr;
- }
-}
-
-int
-prefixof(Adr *a)
-{
- switch(a->type) {
- case D_INDIR+D_CS:
- return 0x2e;
- case D_INDIR+D_DS:
- return 0x3e;
- case D_INDIR+D_ES:
- return 0x26;
- case D_INDIR+D_FS:
- return 0x64;
- case D_INDIR+D_GS:
- return 0x65;
- }
- switch(a->index) {
- case D_CS:
- return 0x2e;
- case D_DS:
- return 0x3e;
- case D_ES:
- return 0x26;
- case D_FS:
- return 0x64;
- case D_GS:
- return 0x65;
- }
- return 0;
-}
-
-int
-oclass(Adr *a)
-{
- vlong v;
- int32 l;
-
- if(a->type >= D_INDIR || a->index != D_NONE) {
- if(a->index != D_NONE && a->scale == 0) {
- if(a->type == D_ADDR) {
- switch(a->index) {
- case D_EXTERN:
- case D_STATIC:
- if(flag_shared)
- return Yiauto;
- else
- return Yi32; /* TO DO: Yi64 */
- case D_AUTO:
- case D_PARAM:
- return Yiauto;
- }
- return Yxxx;
- }
- return Ycol;
- }
- return Ym;
- }
- switch(a->type)
- {
- case D_AL:
- return Yal;
-
- case D_AX:
- return Yax;
-
-/*
- case D_SPB:
-*/
- case D_BPB:
- case D_SIB:
- case D_DIB:
- case D_R8B:
- case D_R9B:
- case D_R10B:
- case D_R11B:
- case D_R12B:
- case D_R13B:
- case D_R14B:
- case D_R15B:
- if(asmode != 64)
- return Yxxx;
- case D_DL:
- case D_BL:
- case D_AH:
- case D_CH:
- case D_DH:
- case D_BH:
- return Yrb;
-
- case D_CL:
- return Ycl;
-
- case D_CX:
- return Ycx;
-
- case D_DX:
- case D_BX:
- return Yrx;
-
- case D_R8: /* not really Yrl */
- case D_R9:
- case D_R10:
- case D_R11:
- case D_R12:
- case D_R13:
- case D_R14:
- case D_R15:
- if(asmode != 64)
- return Yxxx;
- case D_SP:
- case D_BP:
- case D_SI:
- case D_DI:
- return Yrl;
-
- case D_F0+0:
- return Yf0;
-
- case D_F0+1:
- case D_F0+2:
- case D_F0+3:
- case D_F0+4:
- case D_F0+5:
- case D_F0+6:
- case D_F0+7:
- return Yrf;
-
- case D_M0+0:
- case D_M0+1:
- case D_M0+2:
- case D_M0+3:
- case D_M0+4:
- case D_M0+5:
- case D_M0+6:
- case D_M0+7:
- return Ymr;
-
- case D_X0+0:
- case D_X0+1:
- case D_X0+2:
- case D_X0+3:
- case D_X0+4:
- case D_X0+5:
- case D_X0+6:
- case D_X0+7:
- case D_X0+8:
- case D_X0+9:
- case D_X0+10:
- case D_X0+11:
- case D_X0+12:
- case D_X0+13:
- case D_X0+14:
- case D_X0+15:
- return Yxr;
-
- case D_NONE:
- return Ynone;
-
- case D_CS: return Ycs;
- case D_SS: return Yss;
- case D_DS: return Yds;
- case D_ES: return Yes;
- case D_FS: return Yfs;
- case D_GS: return Ygs;
-
- case D_GDTR: return Ygdtr;
- case D_IDTR: return Yidtr;
- case D_LDTR: return Yldtr;
- case D_MSW: return Ymsw;
- case D_TASK: return Ytask;
-
- case D_CR+0: return Ycr0;
- case D_CR+1: return Ycr1;
- case D_CR+2: return Ycr2;
- case D_CR+3: return Ycr3;
- case D_CR+4: return Ycr4;
- case D_CR+5: return Ycr5;
- case D_CR+6: return Ycr6;
- case D_CR+7: return Ycr7;
- case D_CR+8: return Ycr8;
-
- case D_DR+0: return Ydr0;
- case D_DR+1: return Ydr1;
- case D_DR+2: return Ydr2;
- case D_DR+3: return Ydr3;
- case D_DR+4: return Ydr4;
- case D_DR+5: return Ydr5;
- case D_DR+6: return Ydr6;
- case D_DR+7: return Ydr7;
-
- case D_TR+0: return Ytr0;
- case D_TR+1: return Ytr1;
- case D_TR+2: return Ytr2;
- case D_TR+3: return Ytr3;
- case D_TR+4: return Ytr4;
- case D_TR+5: return Ytr5;
- case D_TR+6: return Ytr6;
- case D_TR+7: return Ytr7;
-
- case D_EXTERN:
- case D_STATIC:
- case D_AUTO:
- case D_PARAM:
- return Ym;
-
- case D_CONST:
- case D_ADDR:
- if(a->sym == S) {
- 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;
- }
- return Yi32; /* TO DO: D_ADDR as Yi64 */
-
- case D_BRANCH:
- return Ybr;
- }
- return Yxxx;
-}
-
-void
-asmidx(int scale, int index, int base)
-{
- int i;
-
- switch(index) {
- default:
- goto bad;
-
- case D_NONE:
- i = 4 << 3;
- goto bas;
-
- case D_R8:
- case D_R9:
- case D_R10:
- case D_R11:
- case D_R12:
- case D_R13:
- case D_R14:
- case D_R15:
- if(asmode != 64)
- goto bad;
- case D_AX:
- case D_CX:
- case D_DX:
- case D_BX:
- case D_BP:
- case D_SI:
- case D_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 D_NONE: /* must be mod=00 */
- i |= 5;
- break;
- case D_R8:
- case D_R9:
- case D_R10:
- case D_R11:
- case D_R12:
- case D_R13:
- case D_R14:
- case D_R15:
- if(asmode != 64)
- goto bad;
- case D_AX:
- case D_CX:
- case D_DX:
- case D_BX:
- case D_SP:
- case D_BP:
- case D_SI:
- case D_DI:
- i |= reg[base];
- break;
- }
- *andptr++ = i;
- return;
-bad:
- diag("asmidx: bad address %d/%d/%d", scale, index, base);
- *andptr++ = 0;
- return;
-}
-
-static void
-put4(int32 v)
-{
- andptr[0] = v;
- andptr[1] = v>>8;
- andptr[2] = v>>16;
- andptr[3] = v>>24;
- andptr += 4;
-}
-
-static void
-relput4(Prog *p, Adr *a)
-{
- vlong v;
- Reloc rel, *r;
-
- v = vaddr(a, &rel);
- if(rel.siz != 0) {
- if(rel.siz != 4)
- diag("bad reloc");
- r = addrel(cursym);
- *r = rel;
- r->off = p->pc + andptr - and;
- }
- put4(v);
-}
-
-static void
-put8(vlong v)
-{
- andptr[0] = v;
- andptr[1] = v>>8;
- andptr[2] = v>>16;
- andptr[3] = v>>24;
- andptr[4] = v>>32;
- andptr[5] = v>>40;
- andptr[6] = v>>48;
- andptr[7] = v>>56;
- andptr += 8;
-}
-
-/*
-static void
-relput8(Prog *p, Adr *a)
-{
- vlong v;
- Reloc rel, *r;
-
- v = vaddr(a, &rel);
- if(rel.siz != 0) {
- r = addrel(cursym);
- *r = rel;
- r->siz = 8;
- r->off = p->pc + andptr - and;
- }
- put8(v);
-}
-*/
-
-vlong
-symaddr(Sym *s)
-{
- if(!s->reachable)
- diag("unreachable symbol in symaddr - %s", s->name);
- return s->value;
-}
-
-static vlong
-vaddr(Adr *a, Reloc *r)
-{
- int t;
- vlong v;
- Sym *s;
-
- if(r != nil)
- memset(r, 0, sizeof *r);
-
- t = a->type;
- v = a->offset;
- if(t == D_ADDR)
- t = a->index;
- switch(t) {
- case D_STATIC:
- case D_EXTERN:
- s = a->sym;
- if(!s->reachable)
- diag("unreachable symbol in vaddr - %s", s->name);
- if(r == nil) {
- diag("need reloc for %D", a);
- errorexit();
- }
- r->siz = 4; // TODO: 8 for external symbols
- r->off = -1; // caller must fill in
- r->sym = s;
- r->add = v;
- v = 0;
- if(flag_shared) {
- if(s->type == STLSBSS) {
- r->xadd = r->add - r->siz;
- r->type = D_TLS;
- r->xsym = s;
- } else
- r->type = D_PCREL;
- } else
- r->type = D_ADDR;
- }
- return v;
-}
-
-static void
-asmandsz(Adr *a, int r, int rex, int m64)
-{
- int32 v;
- int t, scale;
- Reloc rel;
-
- USED(m64);
- rex &= (0x40 | Rxr);
- v = a->offset;
- t = a->type;
- rel.siz = 0;
- if(a->index != D_NONE && a->index != D_FS && a->index != D_GS) {
- if(t < D_INDIR) {
- switch(t) {
- default:
- goto bad;
- case D_STATIC:
- case D_EXTERN:
- if(flag_shared)
- goto bad;
- t = D_NONE;
- v = vaddr(a, &rel);
- break;
- case D_AUTO:
- case D_PARAM:
- t = D_SP;
- break;
- }
- } else
- t -= D_INDIR;
- rexflag |= (regrex[(int)a->index] & Rxx) | (regrex[t] & Rxb) | rex;
- if(t == D_NONE) {
- *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- goto putrelv;
- }
- if(v == 0 && rel.siz == 0 && t != D_BP && t != D_R13) {
- *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- return;
- }
- if(v >= -128 && v < 128 && rel.siz == 0) {
- *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- *andptr++ = v;
- return;
- }
- *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- goto putrelv;
- }
- if(t >= D_AL && t <= D_X0+15) {
- if(v)
- goto bad;
- *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
- rexflag |= (regrex[t] & (0x40 | Rxb)) | rex;
- return;
- }
-
- scale = a->scale;
- if(t < D_INDIR) {
- switch(a->type) {
- default:
- goto bad;
- case D_STATIC:
- case D_EXTERN:
- t = D_NONE;
- v = vaddr(a, &rel);
- break;
- case D_AUTO:
- case D_PARAM:
- t = D_SP;
- break;
- }
- scale = 1;
- } else
- t -= D_INDIR;
-
- rexflag |= (regrex[t] & Rxb) | rex;
- if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
- if(flag_shared && t == D_NONE && (a->type == D_STATIC || a->type == D_EXTERN) || asmode != 64) {
- *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
- goto putrelv;
- }
- /* temporary */
- *andptr++ = (0 << 6) | (4 << 0) | (r << 3); /* sib present */
- *andptr++ = (0 << 6) | (4 << 3) | (5 << 0); /* DS:d32 */
- goto putrelv;
- }
- if(t == D_SP || t == D_R12) {
- if(v == 0) {
- *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
- asmidx(scale, D_NONE, t);
- return;
- }
- if(v >= -128 && v < 128) {
- *andptr++ = (1 << 6) | (reg[t] << 0) | (r << 3);
- asmidx(scale, D_NONE, t);
- *andptr++ = v;
- return;
- }
- *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
- asmidx(scale, D_NONE, t);
- goto putrelv;
- }
- if(t >= D_AX && t <= D_R15) {
- if(v == 0 && t != D_BP && t != D_R13) {
- *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
- return;
- }
- if(v >= -128 && v < 128) {
- andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
- andptr[1] = v;
- andptr += 2;
- return;
- }
- *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
- goto putrelv;
- }
- goto bad;
-
-putrelv:
- if(rel.siz != 0) {
- Reloc *r;
-
- if(rel.siz != 4) {
- diag("bad rel");
- goto bad;
- }
- r = addrel(cursym);
- *r = rel;
- r->off = curp->pc + andptr - and;
- } else if(iself && linkmode == LinkExternal && a->type == D_INDIR+D_FS
- && HEADTYPE != Hopenbsd) {
- Reloc *r;
- Sym *s;
-
- r = addrel(cursym);
- r->off = curp->pc + andptr - and;
- r->add = a->offset-tlsoffset;
- r->xadd = r->add;
- r->siz = 4;
- r->type = D_TLS;
- s = lookup("runtime.tlsgm", 0);
- r->sym = s;
- r->xsym = s;
- v = 0;
- }
-
- put4(v);
- return;
-
-bad:
- diag("asmand: bad address %D", a);
- return;
-}
-
-void
-asmand(Adr *a, Adr *ra)
-{
- asmandsz(a, reg[ra->type], regrex[ra->type], 0);
-}
-
-void
-asmando(Adr *a, int o)
-{
- asmandsz(a, o, 0, 0);
-}
-
-static void
-bytereg(Adr *a, char *t)
-{
- if(a->index == D_NONE && (a->type >= D_AX && a->type <= D_R15)) {
- a->type = D_AL + (a->type-D_AX);
- *t = 0;
- }
-}
-
-#define E 0xff
-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},
- 0
-};
-
-int
-isax(Adr *a)
-{
-
- switch(a->type) {
- case D_AX:
- case D_AL:
- case D_AH:
- case D_INDIR+D_AX:
- return 1;
- }
- if(a->index == D_AX)
- return 1;
- return 0;
-}
-
-void
-subreg(Prog *p, int from, int to)
-{
-
- if(debug['Q'])
- print("\n%P s/%R/%R/\n", p, from, to);
-
- if(p->from.type == from)
- p->from.type = to;
- if(p->to.type == from)
- p->to.type = to;
-
- if(p->from.index == from)
- p->from.index = to;
- if(p->to.index == from)
- p->to.index = to;
-
- from += D_INDIR;
- if(p->from.type == from)
- p->from.type = to+D_INDIR;
- if(p->to.type == from)
- p->to.type = to+D_INDIR;
-
- if(debug['Q'])
- print("%P\n", p);
-}
-
-static int
-mediaop(Optab *o, int op, int osize, int z)
-{
- switch(op){
- case Pm:
- case Pe:
- case Pf2:
- case Pf3:
- if(osize != 1){
- if(op != Pm)
- *andptr++ = op;
- *andptr++ = Pm;
- op = o->op[++z];
- break;
- }
- default:
- if(andptr == and || andptr[-1] != Pm)
- *andptr++ = Pm;
- break;
- }
- *andptr++ = op;
- return z;
-}
-
-void
-doasm(Prog *p)
-{
- Optab *o;
- Prog *q, pp;
- uchar *t;
- Movtab *mo;
- int z, op, ft, tt, xo, l, pre;
- vlong v;
- Reloc rel, *r;
- Adr *a;
-
- curp = p; // TODO
-
- o = opindex[p->as];
- if(o == nil) {
- diag("asmins: missing op %P", p);
- return;
- }
-
- pre = prefixof(&p->from);
- if(pre)
- *andptr++ = pre;
- pre = prefixof(&p->to);
- if(pre)
- *andptr++ = pre;
-
- if(p->ft == 0)
- p->ft = oclass(&p->from);
- if(p->tt == 0)
- p->tt = oclass(&p->to);
-
- ft = p->ft * Ymax;
- tt = p->tt * Ymax;
-
- t = o->ytab;
- if(t == 0) {
- 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 */
- *andptr++ = Pe;
- *andptr++ = Pm;
- break;
- case Pq3: /* 16 bit escape, Rex.w, and opcode escape */
- *andptr++ = Pe;
- *andptr++ = Pw;
- *andptr++ = Pm;
- break;
-
- case Pf2: /* xmm opcode escape */
- case Pf3:
- *andptr++ = o->prefix;
- *andptr++ = Pm;
- break;
-
- case Pm: /* opcode escape */
- *andptr++ = Pm;
- break;
-
- case Pe: /* 16 bit escape */
- *andptr++ = Pe;
- break;
-
- case Pw: /* 64-bit escape */
- if(p->mode != 64)
- diag("asmins: illegal 64: %P", p);
- 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)
- diag("asmins: illegal in 64-bit mode: %P", p);
- break;
-
- case Py: /* 64-bit only, no prefix */
- if(p->mode != 64)
- 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) {
- *andptr++ = op;
- op = o->op[++z];
- }
- switch(t[2]) {
- default:
- diag("asmins: unknown z %d %P", t[2], p);
- return;
-
- case Zpseudo:
- break;
-
- case Zlit:
- for(; op = o->op[z]; z++)
- *andptr++ = op;
- break;
-
- case Zlitm_r:
- for(; op = o->op[z]; z++)
- *andptr++ = op;
- asmand(&p->from, &p->to);
- break;
-
- case Zmb_r:
- bytereg(&p->from, &p->ft);
- /* fall through */
- case Zm_r:
- *andptr++ = op;
- asmand(&p->from, &p->to);
- break;
- case Zm2_r:
- *andptr++ = op;
- *andptr++ = o->op[z+1];
- asmand(&p->from, &p->to);
- break;
-
- case Zm_r_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->from, &p->to);
- break;
-
- case Zm_r_xm_nr:
- rexflag = 0;
- mediaop(o, op, t[3], z);
- asmand(&p->from, &p->to);
- break;
-
- case Zm_r_i_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->from, &p->to);
- *andptr++ = p->to.offset;
- break;
-
- case Zm_r_3d:
- *andptr++ = 0x0f;
- *andptr++ = 0x0f;
- asmand(&p->from, &p->to);
- *andptr++ = op;
- break;
-
- case Zibm_r:
- while ((op = o->op[z++]) != 0)
- *andptr++ = op;
- asmand(&p->from, &p->to);
- *andptr++ = p->to.offset;
- break;
-
- case Zaut_r:
- *andptr++ = 0x8d; /* leal */
- if(p->from.type != D_ADDR)
- diag("asmins: Zaut sb type ADDR");
- p->from.type = p->from.index;
- p->from.index = D_NONE;
- asmand(&p->from, &p->to);
- p->from.index = p->from.type;
- p->from.type = D_ADDR;
- break;
-
- case Zm_o:
- *andptr++ = op;
- asmando(&p->from, o->op[z+1]);
- break;
-
- case Zr_m:
- *andptr++ = op;
- asmand(&p->to, &p->from);
- break;
-
- case Zr_m_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->to, &p->from);
- break;
-
- case Zr_m_xm_nr:
- rexflag = 0;
- mediaop(o, op, t[3], z);
- asmand(&p->to, &p->from);
- break;
-
- case Zr_m_i_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->to, &p->from);
- *andptr++ = p->from.offset;
- break;
-
- case Zo_m:
- *andptr++ = op;
- asmando(&p->to, o->op[z+1]);
- break;
-
- case Zo_m64:
- *andptr++ = op;
- asmandsz(&p->to, o->op[z+1], 0, 1);
- break;
-
- case Zm_ibo:
- *andptr++ = op;
- asmando(&p->from, o->op[z+1]);
- *andptr++ = vaddr(&p->to, nil);
- break;
-
- case Zibo_m:
- *andptr++ = op;
- asmando(&p->to, o->op[z+1]);
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Zibo_m_xm:
- z = mediaop(o, op, t[3], z);
- asmando(&p->to, o->op[z+1]);
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Z_ib:
- case Zib_:
- if(t[2] == Zib_)
- a = &p->from;
- else
- a = &p->to;
- *andptr++ = op;
- *andptr++ = vaddr(a, nil);
- break;
-
- case Zib_rp:
- rexflag |= regrex[p->to.type] & (Rxb|0x40);
- *andptr++ = op + reg[p->to.type];
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Zil_rp:
- rexflag |= regrex[p->to.type] & Rxb;
- *andptr++ = op + reg[p->to.type];
- if(o->prefix == Pe) {
- v = vaddr(&p->from, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, &p->from);
- break;
-
- case Zo_iw:
- *andptr++ = op;
- if(p->from.type != D_NONE){
- v = vaddr(&p->from, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- break;
-
- case Ziq_rp:
- v = vaddr(&p->from, &rel);
- l = v>>32;
- if(l == 0 && rel.siz != 8){
- //p->mark |= 0100;
- //print("zero: %llux %P\n", v, p);
- rexflag &= ~(0x40|Rxw);
- rexflag |= regrex[p->to.type] & Rxb;
- *andptr++ = 0xb8 + reg[p->to.type];
- if(rel.type != 0) {
- r = addrel(cursym);
- *r = rel;
- r->off = p->pc + andptr - and;
- }
- put4(v);
- }else if(l == -1 && (v&((uvlong)1<<31))!=0){ /* sign extend */
- //p->mark |= 0100;
- //print("sign: %llux %P\n", v, p);
- *andptr ++ = 0xc7;
- asmando(&p->to, 0);
- put4(v);
- }else{ /* need all 8 */
- //print("all: %llux %P\n", v, p);
- rexflag |= regrex[p->to.type] & Rxb;
- *andptr++ = op + reg[p->to.type];
- if(rel.type != 0) {
- r = addrel(cursym);
- *r = rel;
- r->off = p->pc + andptr - and;
- }
- put8(v);
- }
- break;
-
- case Zib_rr:
- *andptr++ = op;
- asmand(&p->to, &p->to);
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Z_il:
- case Zil_:
- if(t[2] == Zil_)
- a = &p->from;
- else
- a = &p->to;
- *andptr++ = op;
- if(o->prefix == Pe) {
- v = vaddr(a, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, a);
- break;
-
- case Zm_ilo:
- case Zilo_m:
- *andptr++ = op;
- if(t[2] == Zilo_m) {
- a = &p->from;
- asmando(&p->to, o->op[z+1]);
- } else {
- a = &p->to;
- asmando(&p->from, o->op[z+1]);
- }
- if(o->prefix == Pe) {
- v = vaddr(a, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, a);
- break;
-
- case Zil_rr:
- *andptr++ = op;
- asmand(&p->to, &p->to);
- if(o->prefix == Pe) {
- v = vaddr(&p->from, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, &p->from);
- break;
-
- case Z_rp:
- rexflag |= regrex[p->to.type] & (Rxb|0x40);
- *andptr++ = op + reg[p->to.type];
- break;
-
- case Zrp_:
- rexflag |= regrex[p->from.type] & (Rxb|0x40);
- *andptr++ = op + reg[p->from.type];
- break;
-
- case Zclr:
- *andptr++ = op;
- asmand(&p->to, &p->to);
- break;
-
- case Zcall:
- q = p->pcond;
- if(q == nil) {
- diag("call without target");
- errorexit();
- }
- if(q->as != ATEXT) {
- // Could handle this case by making D_PCREL
- // record the Prog* instead of the Sym*, but let's
- // wait until the need arises.
- diag("call of non-TEXT %P", q);
- errorexit();
- }
- *andptr++ = op;
- r = addrel(cursym);
- r->off = p->pc + andptr - and;
- r->sym = q->from.sym;
- r->type = D_PCREL;
- r->siz = 4;
- put4(0);
- break;
-
- case Zbr:
- case Zjmp:
- case Zloop:
- // TODO: jump across functions needs reloc
- q = p->pcond;
- if(q == nil) {
- diag("jmp/branch/loop without target");
- errorexit();
- }
- if(q->as == ATEXT) {
- if(t[2] == Zbr) {
- diag("branch to ATEXT");
- errorexit();
- }
- *andptr++ = o->op[z+1];
- r = addrel(cursym);
- r->off = p->pc + andptr - and;
- r->sym = q->from.sym;
- r->type = D_PCREL;
- r->siz = 4;
- put4(0);
- break;
- }
- // Assumes q is in this function.
- // TODO: Check in input, preserve in brchain.
-
- // Fill in backward jump now.
- if(p->back & 1) {
- v = q->pc - (p->pc + 2);
- if(v >= -128) {
- if(p->as == AJCXZL)
- *andptr++ = 0x67;
- *andptr++ = op;
- *andptr++ = v;
- } else if(t[2] == Zloop) {
- diag("loop too far: %P", p);
- } else {
- v -= 5-2;
- if(t[2] == Zbr) {
- *andptr++ = 0x0f;
- v--;
- }
- *andptr++ = o->op[z+1];
- *andptr++ = v;
- *andptr++ = v>>8;
- *andptr++ = v>>16;
- *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)
- *andptr++ = 0x67;
- *andptr++ = op;
- *andptr++ = 0;
- } else if(t[2] == Zloop) {
- diag("loop too far: %P", p);
- } else {
- if(t[2] == Zbr)
- *andptr++ = 0x0f;
- *andptr++ = o->op[z+1];
- *andptr++ = 0;
- *andptr++ = 0;
- *andptr++ = 0;
- *andptr++ = 0;
- }
- break;
-
-/*
- v = q->pc - p->pc - 2;
- if((v >= -128 && v <= 127) || p->pc == -1 || q->pc == -1) {
- *andptr++ = op;
- *andptr++ = v;
- } else {
- v -= 5-2;
- if(t[2] == Zbr) {
- *andptr++ = 0x0f;
- v--;
- }
- *andptr++ = o->op[z+1];
- *andptr++ = v;
- *andptr++ = v>>8;
- *andptr++ = v>>16;
- *andptr++ = v>>24;
- }
-*/
- break;
-
- case Zbyte:
- v = vaddr(&p->from, &rel);
- if(rel.siz != 0) {
- rel.siz = op;
- r = addrel(cursym);
- *r = rel;
- r->off = p->pc + andptr - and;
- }
- *andptr++ = v;
- if(op > 1) {
- *andptr++ = v>>8;
- if(op > 2) {
- *andptr++ = v>>16;
- *andptr++ = v>>24;
- if(op > 4) {
- *andptr++ = v>>32;
- *andptr++ = v>>40;
- *andptr++ = v>>48;
- *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.type;
- if(z >= D_BP && z <= D_DI) {
- if(isax(&p->to) || p->to.type == D_NONE) {
- // We certainly don't want to exchange
- // with AX if the op is MUL or DIV.
- *andptr++ = 0x87; /* xchg lhs,bx */
- asmando(&p->from, reg[D_BX]);
- subreg(&pp, z, D_BX);
- doasm(&pp);
- *andptr++ = 0x87; /* xchg lhs,bx */
- asmando(&p->from, reg[D_BX]);
- } else {
- *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
- subreg(&pp, z, D_AX);
- doasm(&pp);
- *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
- }
- return;
- }
- z = p->to.type;
- if(z >= D_BP && z <= D_DI) {
- if(isax(&p->from)) {
- *andptr++ = 0x87; /* xchg rhs,bx */
- asmando(&p->to, reg[D_BX]);
- subreg(&pp, z, D_BX);
- doasm(&pp);
- *andptr++ = 0x87; /* xchg rhs,bx */
- asmando(&p->to, reg[D_BX]);
- } else {
- *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
- subreg(&pp, z, D_AX);
- doasm(&pp);
- *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
- }
- return;
- }
- }
- diag("doasm: notfound from=%ux to=%ux %P", p->from.type, p->to.type, p);
- return;
-
-mfound:
- switch(mo->code) {
- default:
- diag("asmins: unknown mov %d %P", mo->code, p);
- break;
-
- case 0: /* lit */
- for(z=0; t[z]!=E; z++)
- *andptr++ = t[z];
- break;
-
- case 1: /* r,m */
- *andptr++ = t[0];
- asmando(&p->to, t[1]);
- break;
-
- case 2: /* m,r */
- *andptr++ = t[0];
- asmando(&p->from, t[1]);
- break;
-
- case 3: /* r,m - 2op */
- *andptr++ = t[0];
- *andptr++ = t[1];
- asmando(&p->to, t[2]);
- rexflag |= regrex[p->from.type] & (Rxr|0x40);
- break;
-
- case 4: /* m,r - 2op */
- *andptr++ = t[0];
- *andptr++ = t[1];
- asmando(&p->from, t[2]);
- rexflag |= regrex[p->to.type] & (Rxr|0x40);
- break;
-
- case 5: /* load full pointer, trash heap */
- if(t[0])
- *andptr++ = t[0];
- switch(p->to.index) {
- default:
- goto bad;
- case D_DS:
- *andptr++ = 0xc5;
- break;
- case D_SS:
- *andptr++ = 0x0f;
- *andptr++ = 0xb2;
- break;
- case D_ES:
- *andptr++ = 0xc4;
- break;
- case D_FS:
- *andptr++ = 0x0f;
- *andptr++ = 0xb4;
- break;
- case D_GS:
- *andptr++ = 0x0f;
- *andptr++ = 0xb5;
- break;
- }
- asmand(&p->from, &p->to);
- break;
-
- case 6: /* double shift */
- if(t[0] == Pw){
- if(p->mode != 64)
- diag("asmins: illegal 64: %P", p);
- rexflag |= Pw;
- t++;
- }else if(t[0] == Pe){
- *andptr++ = Pe;
- t++;
- }
- z = p->from.type;
- switch(z) {
- default:
- goto bad;
- case D_CONST:
- *andptr++ = 0x0f;
- *andptr++ = t[0];
- asmandsz(&p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
- *andptr++ = p->from.offset;
- break;
- case D_CL:
- case D_CX:
- *andptr++ = 0x0f;
- *andptr++ = t[1];
- asmandsz(&p->to, reg[(int)p->from.index], regrex[(int)p->from.index], 0);
- break;
- }
- break;
- }
-}
-
-void
-asmins(Prog *p)
-{
- int n, np, c;
- Reloc *r;
-
- rexflag = 0;
- andptr = and;
- asmode = p->mode;
- doasm(p);
- if(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)
- diag("asmins: illegal in mode %d: %P", p->mode, p);
- n = andptr - and;
- for(np = 0; np < n; np++) {
- c = and[np];
- if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26)
- break;
- }
- memmove(and+np+1, and+np, n-np);
- and[np] = 0x40 | rexflag;
- andptr++;
- }
- n = andptr - and;
- for(r=cursym->r+cursym->nr; r-- > cursym->r; ) {
- if(r->off < p->pc)
- break;
- if(rexflag)
- r->off++;
- if(r->type == D_PCREL)
- r->add -= p->pc + n - (r->off + r->siz);
- }
-}
diff --git a/src/cmd/8a/a.h b/src/cmd/8a/a.h
index c5c22d7ba..adc388ca9 100644
--- a/src/cmd/8a/a.h
+++ b/src/cmd/8a/a.h
@@ -29,9 +29,9 @@
// THE SOFTWARE.
#include <bio.h>
+#include <link.h>
#include "../8l/8.out.h"
-
#ifndef EXTERN
#define EXTERN extern
#endif
@@ -45,10 +45,8 @@
typedef struct Sym Sym;
typedef struct Ref Ref;
-typedef struct Gen Gen;
typedef struct Io Io;
-typedef struct Hist Hist;
-typedef struct Gen2 Gen2;
+typedef struct Addr2 Addr2;
#define MAXALIGN 7
#define FPCHIP 1
@@ -97,37 +95,11 @@ struct Io
};
#define I ((Io*)0)
-EXTERN struct
-{
- Sym* sym;
- short type;
-} h[NSYM];
-
-struct Gen
-{
- double dval;
- char sval[8];
- int32 offset;
- int32 offset2;
- Sym* sym;
- short type;
- short index;
- short scale;
-};
-struct Gen2
-{
- Gen from;
- Gen to;
-};
-
-struct Hist
+struct Addr2
{
- Hist* link;
- char* name;
- int32 line;
- int32 offset;
+ Addr from;
+ Addr to;
};
-#define H ((Hist*)0)
enum
{
@@ -137,14 +109,11 @@ enum
CPREPROC,
};
-
-EXTERN char debug[256];
+EXTERN int debug[256];
EXTERN Sym* hash[NHASH];
EXTERN char** Dlist;
EXTERN int nDlist;
-EXTERN Hist* ehist;
EXTERN int newflag;
-EXTERN Hist* hist;
EXTERN char* hunk;
EXTERN char** include;
EXTERN Io* iofree;
@@ -155,10 +124,9 @@ EXTERN int nerrors;
EXTERN int32 nhunk;
EXTERN int ninclude;
EXTERN int32 nsymb;
-EXTERN Gen nullgen;
+EXTERN Addr nullgen;
EXTERN char* outfile;
EXTERN int pass;
-EXTERN char* pathname;
EXTERN int32 pc;
EXTERN int peekc;
EXTERN int32 stmtline;
@@ -168,6 +136,8 @@ EXTERN int thechar;
EXTERN char* thestring;
EXTERN int32 thunk;
EXTERN Biobuf obuf;
+EXTERN Link* ctxt;
+EXTERN Biobuf bstdout;
void* alloc(int32);
void* allocn(void*, int32, int32);
@@ -188,12 +158,9 @@ void cinit(void);
void checkscale(int);
void pinit(char*);
void cclean(void);
-int isreg(Gen*);
-void outcode(int, Gen2*);
+int isreg(Addr*);
+void outcode(int, Addr2*);
void outhist(void);
-void zaddr(Gen*, int);
-void zname(char*, int, int);
-void ieeedtod(Ieee*, double);
int filbuf(void);
Sym* getsym(void);
void domacro(void);
diff --git a/src/cmd/8a/a.y b/src/cmd/8a/a.y
index 13ccc985b..d7ff623da 100644
--- a/src/cmd/8a/a.y
+++ b/src/cmd/8a/a.y
@@ -44,8 +44,8 @@
} con2;
double dval;
char sval[8];
- Gen gen;
- Gen2 gen2;
+ Addr addr;
+ Addr2 addr2;
}
%left '|'
%left '^'
@@ -62,9 +62,9 @@
%token <sym> LNAME LLAB LVAR
%type <lval> con expr pointer offset
%type <con2> con2
-%type <gen> mem imm imm2 reg nam rel rem rim rom omem nmem
-%type <gen2> nonnon nonrel nonrem rimnon rimrem remrim
-%type <gen2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
+%type <addr> mem imm imm2 reg nam rel rem rim rom omem nmem
+%type <addr2> nonnon nonrel nonrem rimnon rimrem remrim
+%type <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
%%
prog:
| prog
@@ -366,14 +366,12 @@ rel:
if(pass == 2)
yyerror("undefined label: %s", $1->name);
$$.type = D_BRANCH;
- $$.sym = $1;
$$.offset = $2;
}
| LLAB offset
{
$$ = nullgen;
$$.type = D_BRANCH;
- $$.sym = $1;
$$.offset = $1->value + $2;
}
@@ -431,31 +429,31 @@ imm:
{
$$ = nullgen;
$$.type = D_SCONST;
- memcpy($$.sval, $2, sizeof($$.sval));
+ memcpy($$.u.sval, $2, sizeof($$.u.sval));
}
| '$' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = $2;
+ $$.u.dval = $2;
}
| '$' '(' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = $3;
+ $$.u.dval = $3;
}
| '$' '(' '-' LFCONST ')'
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = -$4;
+ $$.u.dval = -$4;
}
| '$' '-' LFCONST
{
$$ = nullgen;
$$.type = D_FCONST;
- $$.dval = -$3;
+ $$.u.dval = -$3;
}
imm2:
@@ -590,14 +588,14 @@ nam:
{
$$ = nullgen;
$$.type = $4;
- $$.sym = $1;
+ $$.sym = linklookup(ctxt, $1->name, 0);
$$.offset = $2;
}
| LNAME '<' '>' offset '(' LSB ')'
{
$$ = nullgen;
$$.type = D_STATIC;
- $$.sym = $1;
+ $$.sym = linklookup(ctxt, $1->name, 1);
$$.offset = $4;
}
diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c
index f2ccc3361..32c099b75 100644
--- a/src/cmd/8a/lex.c
+++ b/src/cmd/8a/lex.c
@@ -57,56 +57,75 @@ pathchar(void)
return '/';
}
+int
+Lconv(Fmt *fp)
+{
+ return linklinefmt(ctxt, fp);
+}
+
+void
+dodef(char *p)
+{
+ if(nDlist%8 == 0)
+ Dlist = allocn(Dlist, nDlist*sizeof(char *),
+ 8*sizeof(char *));
+ Dlist[nDlist++] = p;
+}
+
+void
+usage(void)
+{
+ print("usage: %ca [options] file.c...\n", thechar);
+ flagprint(1);
+ errorexit();
+}
void
main(int argc, char *argv[])
{
char *p;
- int c;
thechar = '8';
thestring = "386";
+ ctxt = linknew(&link386);
+ ctxt->diag = yyerror;
+ ctxt->bso = &bstdout;
+ Binit(&bstdout, 1, OWRITE);
+ listinit8();
+ fmtinstall('L', Lconv);
+
+ // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+ // but not other values.
+ p = getgoarch();
+ if(strncmp(p, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
+
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
cinit();
outfile = 0;
setinclude(".");
- ARGBEGIN {
- default:
- c = ARGC();
- if(c >= 0 && c < sizeof(debug))
- debug[c] = 1;
- break;
-
- case 'o':
- outfile = ARGF();
- break;
-
- case 'D':
- p = ARGF();
- if(p) {
- if (nDlist%8 == 0)
- Dlist = allocn(Dlist, nDlist*sizeof(char *),
- 8*sizeof(char *));
- Dlist[nDlist++] = p;
- }
- break;
-
- case 'I':
- p = ARGF();
- setinclude(p);
- break;
- } ARGEND
- if(*argv == 0) {
- print("usage: %ca [-options] file.s\n", thechar);
- errorexit();
- }
+
+ flagfn1("D", "name[=value]: add #define", dodef);
+ flagfn1("I", "dir: add dir to include path", setinclude);
+ flagcount("S", "print assembly and machine code", &debug['S']);
+ flagcount("m", "debug preprocessor macros", &debug['m']);
+ flagstr("o", "file: set output file", &outfile);
+ flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
+
+ flagparse(&argc, &argv, usage);
+ ctxt->debugasm = debug['S'];
+
+ if(argc < 1)
+ usage();
if(argc > 1){
print("can't assemble multiple files\n");
errorexit();
}
+
if(assemble(argv[0]))
errorexit();
+ Bflush(&bstdout);
exits(0);
}
@@ -145,30 +164,22 @@ assemble(char *file)
errorexit();
}
Binit(&obuf, of, OWRITE);
-
- pass = 1;
- pinit(file);
-
- Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
-
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- if(nerrors) {
+ Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
+ Bprint(&obuf, "!\n");
+
+ for(pass = 1; pass <= 2; pass++) {
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
cclean();
- return nerrors;
+ if(nerrors)
+ return nerrors;
}
- Bprint(&obuf, "\n!\n");
-
- pass = 2;
- outhist();
- pinit(file);
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- cclean();
- return nerrors;
+ writeobj(ctxt, &obuf);
+ Bflush(&obuf);
+ return 0;
}
struct
@@ -225,6 +236,7 @@ struct
"ES", LSREG, D_ES,
"FS", LSREG, D_FS,
"GS", LSREG, D_GS,
+ "TLS", LSREG, D_TLS,
"GDTR", LBREG, D_GDTR,
"IDTR", LBREG, D_IDTR,
@@ -778,6 +790,7 @@ struct
"PSUBW", LTYPE3, APSUBW,
"PUNPCKHQDQ", LTYPE3, APUNPCKHQDQ,
"PUNPCKLQDQ", LTYPE3, APUNPCKLQDQ,
+ "PXOR", LTYPE3, APXOR,
"RCPPS", LTYPE3, ARCPPS,
"RCPSS", LTYPE3, ARCPSS,
"RSQRTPS", LTYPE3, ARSQRTPS,
@@ -810,15 +823,8 @@ cinit(void)
Sym *s;
int i;
- nullgen.sym = S;
- nullgen.offset = 0;
- if(FPCHIP)
- nullgen.dval = 0;
- for(i=0; i<sizeof(nullgen.sval); i++)
- nullgen.sval[i] = 0;
nullgen.type = D_NONE;
nullgen.index = D_NONE;
- nullgen.scale = 0;
nerrors = 0;
iostack = I;
@@ -834,13 +840,6 @@ cinit(void)
s->type = itab[i].type;
s->value = itab[i].value;
}
-
- pathname = allocn(pathname, 0, 100);
- if(getwd(pathname, 99) == 0) {
- pathname = allocn(pathname, 100, 900);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
- }
}
void
@@ -868,252 +867,43 @@ syminit(Sym *s)
void
cclean(void)
{
- Gen2 g2;
+ Addr2 g2;
g2.from = nullgen;
g2.to = nullgen;
outcode(AEND, &g2);
- Bflush(&obuf);
}
-void
-zname(char *n, int t, int s)
-{
-
- BPUTLE2(&obuf, ANAME); /* as(2) */
- BPUTC(&obuf, t); /* type */
- BPUTC(&obuf, s); /* sym */
- while(*n) {
- BPUTC(&obuf, *n);
- n++;
- }
- BPUTC(&obuf, 0);
-}
+static Prog *lastpc;
void
-zaddr(Gen *a, int s)
+outcode(int a, Addr2 *g2)
{
- int32 l;
- int i, t;
- char *n;
- Ieee e;
-
- t = 0;
- if(a->index != D_NONE || a->scale != 0)
- t |= T_INDEX;
- if(a->offset != 0)
- t |= T_OFFSET;
- if(s != 0)
- t |= T_SYM;
-
- switch(a->type) {
- default:
- t |= T_TYPE;
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_CONST2:
- t |= T_OFFSET|T_OFFSET2;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- case D_NONE:
- break;
- }
- BPUTC(&obuf, t);
-
- if(t & T_INDEX) { /* implies index, scale */
- BPUTC(&obuf, a->index);
- BPUTC(&obuf, a->scale);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- BPUTLE4(&obuf, l);
- }
- if(t & T_OFFSET2) {
- l = a->offset2;
- BPUTLE4(&obuf, l);
- }
- if(t & T_SYM) /* implies sym */
- BPUTC(&obuf, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->dval);
- BPUTLE4(&obuf, e.l);
- BPUTLE4(&obuf, e.h);
- return;
- }
- if(t & T_SCONST) {
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(&obuf, *n);
- n++;
- }
- return;
- }
- if(t & T_TYPE)
- BPUTC(&obuf, a->type);
-}
-
-void
-outcode(int a, Gen2 *g2)
-{
- int sf, st, t;
- Sym *s;
-
+ Prog *p;
+ Plist *pl;
+
if(pass == 1)
goto out;
-jackpot:
- sf = 0;
- s = g2->from.sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = g2->from.type;
- if(t == D_ADDR)
- t = g2->from.index;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = g2->to.sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = g2->to.type;
- if(t == D_ADDR)
- t = g2->to.index;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- BPUTLE2(&obuf, a);
- BPUTLE4(&obuf, stmtline);
- zaddr(&g2->from, sf);
- zaddr(&g2->to, st);
+ p = malloc(sizeof *p);
+ memset(p, 0, sizeof *p);
+ p->as = a;
+ p->lineno = stmtline;
+ p->from = g2->from;
+ p->to = g2->to;
+ p->pc = pc;
+
+ if(lastpc == nil) {
+ pl = linknewplist(ctxt);
+ pl->firstpc = p;
+ } else
+ lastpc->link = p;
+ lastpc = p;
out:
if(a != AGLOBL && a != ADATA)
pc++;
}
-void
-outhist(void)
-{
- Gen g;
- Hist *h;
- char *p, *q, *op, c;
- int n;
- char *tofree;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
-
- g = nullgen;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p != nil && goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- op = 0;
- if(systemtype(Windows) && p && p[1] == ':'){
- c = p[2];
- } else if(p && p[0] != c && h->offset == 0 && pathname){
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname;
- c = p[2];
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = strchr(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- BPUTLE2(&obuf, ANAME);
- BPUTC(&obuf, D_FILE); /* type */
- BPUTC(&obuf, 1); /* sym */
- BPUTC(&obuf, '<');
- Bwrite(&obuf, p, n);
- BPUTC(&obuf, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- g.offset = h->offset;
-
- BPUTLE2(&obuf, AHISTORY);
- BPUTLE4(&obuf, h->line);
- zaddr(&nullgen, 0);
- zaddr(&g, 0);
-
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
#include "../cc/lexbody"
#include "../cc/macbody"
diff --git a/src/cmd/8a/y.tab.c b/src/cmd/8a/y.tab.c
index aec4856f6..f48c9fe1f 100644
--- a/src/cmd/8a/y.tab.c
+++ b/src/cmd/8a/y.tab.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -44,7 +47,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -52,51 +55,11 @@
/* Pure parsers. */
#define YYPURE 0
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
/* Using locations. */
#define YYLSP_NEEDED 0
-/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 31 "a.y"
-
-#include <u.h>
-#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
-#include <libc.h>
-#include "a.h"
-#include "../../pkg/runtime/funcdata.h"
-
-
-/* Line 268 of yacc.c */
-#line 80 "y.tab.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -176,13 +139,38 @@
+/* Copy the first part of user declarations. */
+#line 31 "a.y"
+
+#include <u.h>
+#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
+#include <libc.h>
+#include "a.h"
+#include "../../pkg/runtime/funcdata.h"
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c */
#line 38 "a.y"
-
+{
Sym *sym;
int32 lval;
struct {
@@ -191,25 +179,24 @@ typedef union YYSTYPE
} con2;
double dval;
char sval[8];
- Gen gen;
- Gen2 gen2;
-
-
-
-/* Line 293 of yacc.c */
-#line 201 "y.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+ Addr addr;
+ Addr2 addr2;
+}
+/* Line 193 of yacc.c. */
+#line 187 "y.tab.c"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
+
/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 213 "y.tab.c"
+/* Line 216 of yacc.c. */
+#line 200 "y.tab.c"
#ifdef short
# undef short
@@ -284,14 +271,14 @@ typedef short int yytype_int16;
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static int
-YYID (int yyi)
+YYID (int i)
#else
static int
-YYID (yyi)
- int yyi;
+YYID (i)
+ int i;
#endif
{
- return yyi;
+ return i;
}
#endif
@@ -312,11 +299,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# endif
@@ -339,24 +326,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+# if (defined __cplusplus && ! defined _STDLIB_H \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@@ -372,9 +359,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- yytype_int16 yyss_alloc;
- YYSTYPE yyvs_alloc;
-};
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -385,27 +372,6 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
@@ -423,7 +389,24 @@ union yyalloc
while (YYID (0))
# endif
# endif
-#endif /* !YYCOPY_NEEDED */
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
@@ -564,13 +547,13 @@ static const yytype_uint16 yyrline[] =
175, 180, 185, 192, 200, 205, 213, 218, 223, 232,
233, 236, 241, 251, 256, 266, 271, 276, 283, 288,
296, 304, 314, 323, 334, 335, 338, 339, 340, 344,
- 348, 349, 350, 353, 354, 357, 363, 372, 381, 386,
- 391, 396, 401, 406, 413, 419, 430, 436, 442, 448,
- 454, 462, 471, 476, 481, 486, 493, 494, 497, 503,
- 509, 515, 524, 533, 542, 547, 552, 558, 566, 576,
- 580, 589, 596, 605, 608, 612, 618, 619, 623, 626,
- 627, 631, 635, 639, 643, 649, 650, 654, 658, 662,
- 666, 670, 674, 678, 682, 686
+ 348, 349, 350, 353, 354, 357, 363, 371, 379, 384,
+ 389, 394, 399, 404, 411, 417, 428, 434, 440, 446,
+ 452, 460, 469, 474, 479, 484, 491, 492, 495, 501,
+ 507, 513, 522, 531, 540, 545, 550, 556, 564, 574,
+ 578, 587, 594, 603, 606, 610, 616, 617, 621, 624,
+ 625, 629, 633, 637, 641, 647, 648, 652, 656, 660,
+ 664, 668, 672, 676, 680, 684
};
#endif
@@ -585,12 +568,12 @@ static const char *const yytname[] =
"LTYPEM", "LTYPEI", "LTYPEG", "LTYPEXC", "LTYPEX", "LTYPEPC", "LTYPEF",
"LCONST", "LFP", "LPC", "LSB", "LBREG", "LLREG", "LSREG", "LFREG",
"LXREG", "LFCONST", "LSCONST", "LSP", "LNAME", "LLAB", "LVAR", "':'",
- "';'", "'='", "','", "'('", "')'", "'$'", "'~'", "$accept", "prog",
- "$@1", "line", "$@2", "$@3", "inst", "nonnon", "rimrem", "remrim",
- "rimnon", "nonrem", "nonrel", "spec1", "spec2", "spec3", "spec4",
- "spec5", "spec6", "spec7", "spec8", "spec9", "spec10", "spec11",
- "spec12", "rem", "rom", "rim", "rel", "reg", "imm", "imm2", "con2",
- "mem", "omem", "nmem", "nam", "offset", "pointer", "con", "expr", 0
+ "';'", "'='", "','", "'('", "')'", "'$'", "'~'", "$accept", "prog", "@1",
+ "line", "@2", "@3", "inst", "nonnon", "rimrem", "remrim", "rimnon",
+ "nonrem", "nonrel", "spec1", "spec2", "spec3", "spec4", "spec5", "spec6",
+ "spec7", "spec8", "spec9", "spec10", "spec11", "spec12", "rem", "rom",
+ "rim", "rel", "reg", "imm", "imm2", "con2", "mem", "omem", "nmem", "nam",
+ "offset", "pointer", "con", "expr", 0
};
#endif
@@ -646,8 +629,8 @@ static const yytype_uint8 yyr2[] =
3, 4, 4, 3, 3, 3
};
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@@ -738,7 +721,8 @@ static const yytype_int16 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF, syntax error. */
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint16 yytable[] =
{
@@ -799,12 +783,6 @@ static const yytype_uint16 yytable[] =
170, 171, 172, 173, 174, 175, 176
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-104))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
static const yytype_int16 yycheck[] =
{
10, 10, 10, 13, 0, 13, 8, 13, 11, 10,
@@ -910,18 +888,9 @@ static const yytype_uint8 yystos[] =
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
+ Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
#define YYRECOVERING() (!!yyerrstatus)
@@ -931,6 +900,7 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@@ -972,10 +942,19 @@ while (YYID (0))
#endif
-/* This macro is provided for backward compatibility. */
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
#endif
@@ -1079,20 +1058,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -1126,11 +1102,11 @@ yy_reduce_print (yyvsp, yyrule)
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ fprintf (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
);
- YYFPRINTF (stderr, "\n");
+ fprintf (stderr, "\n");
}
}
@@ -1167,6 +1143,7 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
+
#if YYERROR_VERBOSE
@@ -1269,142 +1246,115 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return 2 if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- /* Internationalized format string. */
- const char *yyformat = 0;
- /* Arguments of yyformat. */
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
- int yycount = 0;
-
- /* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yytoken != YYEMPTY)
- {
- int yyn = yypact[*yyssp];
- yyarg[yycount++] = yytname[yytoken];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
- }
- }
+ int yyn = yypact[yystate];
- switch (yycount)
- {
-# define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
- }
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return 1;
- }
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyformat += 2;
- }
- else
- {
- yyp++;
- yyformat++;
- }
- }
- return 0;
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
}
#endif /* YYERROR_VERBOSE */
+
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@@ -1436,9 +1386,10 @@ yydestruct (yymsg, yytype, yyvaluep)
break;
}
}
-
+
/* Prevent warnings from -Wmissing-prototypes. */
+
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
@@ -1454,16 +1405,18 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
-/* The lookahead symbol. */
+
+/* The look-ahead symbol. */
int yychar;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
int yynerrs;
+
/*----------.
| yyparse. |
`----------*/
@@ -1490,37 +1443,14 @@ yyparse ()
#endif
#endif
{
- int yystate;
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
-
- /* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
-
- YYSIZE_T yystacksize;
-
+
+ int yystate;
int yyn;
int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
@@ -1528,28 +1458,51 @@ yyparse ()
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yystacksize = YYINITDEPTH;
-
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
+ yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
+
yyssp = yyss;
yyvsp = yyvs;
@@ -1579,6 +1532,7 @@ yyparse ()
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
+
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
@@ -1586,6 +1540,7 @@ yyparse ()
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
+
&yystacksize);
yyss = yyss1;
@@ -1608,8 +1563,9 @@ yyparse ()
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@@ -1620,6 +1576,7 @@ yyparse ()
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
+
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
@@ -1629,9 +1586,6 @@ yyparse ()
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
- if (yystate == YYFINAL)
- YYACCEPT;
-
goto yybackup;
/*-----------.
@@ -1640,16 +1594,16 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
+ look-ahead token if we need one and don't already have one. */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
+ if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -1675,22 +1629,26 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yytable_value_is_error (yyn))
- goto yyerrlab;
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
- /* Shift the lookahead token. */
+ /* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the shifted token. */
- yychar = YYEMPTY;
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
@@ -1730,8 +1688,6 @@ yyreduce:
switch (yyn)
{
case 3:
-
-/* Line 1806 of yacc.c */
#line 71 "a.y"
{
stmtline = lineno;
@@ -1739,8 +1695,6 @@ yyreduce:
break;
case 5:
-
-/* Line 1806 of yacc.c */
#line 78 "a.y"
{
if((yyvsp[(1) - (2)].sym)->value != pc)
@@ -1750,8 +1704,6 @@ yyreduce:
break;
case 7:
-
-/* Line 1806 of yacc.c */
#line 85 "a.y"
{
(yyvsp[(1) - (2)].sym)->type = LLAB;
@@ -1760,8 +1712,6 @@ yyreduce:
break;
case 12:
-
-/* Line 1806 of yacc.c */
#line 96 "a.y"
{
(yyvsp[(1) - (3)].sym)->type = LVAR;
@@ -1770,8 +1720,6 @@ yyreduce:
break;
case 13:
-
-/* Line 1806 of yacc.c */
#line 101 "a.y"
{
if((yyvsp[(1) - (3)].sym)->value != (yyvsp[(3) - (3)].lval))
@@ -1781,586 +1729,462 @@ yyreduce:
break;
case 14:
-
-/* Line 1806 of yacc.c */
#line 106 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 15:
-
-/* Line 1806 of yacc.c */
#line 107 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 16:
-
-/* Line 1806 of yacc.c */
#line 108 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 17:
-
-/* Line 1806 of yacc.c */
#line 109 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 18:
-
-/* Line 1806 of yacc.c */
#line 110 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 19:
-
-/* Line 1806 of yacc.c */
#line 111 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 20:
-
-/* Line 1806 of yacc.c */
#line 112 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 21:
-
-/* Line 1806 of yacc.c */
#line 113 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 22:
-
-/* Line 1806 of yacc.c */
#line 114 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 23:
-
-/* Line 1806 of yacc.c */
#line 115 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 24:
-
-/* Line 1806 of yacc.c */
#line 116 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 25:
-
-/* Line 1806 of yacc.c */
#line 117 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 26:
-
-/* Line 1806 of yacc.c */
#line 118 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 27:
-
-/* Line 1806 of yacc.c */
#line 119 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 28:
-
-/* Line 1806 of yacc.c */
#line 120 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 29:
-
-/* Line 1806 of yacc.c */
#line 121 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 30:
-
-/* Line 1806 of yacc.c */
#line 122 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 31:
-
-/* Line 1806 of yacc.c */
#line 123 "a.y"
- { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].gen2)); }
+ { outcode((yyvsp[(1) - (2)].lval), &(yyvsp[(2) - (2)].addr2)); }
break;
case 32:
-
-/* Line 1806 of yacc.c */
#line 126 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = nullgen;
}
break;
case 33:
-
-/* Line 1806 of yacc.c */
#line 131 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = nullgen;
}
break;
case 34:
-
-/* Line 1806 of yacc.c */
#line 138 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 35:
-
-/* Line 1806 of yacc.c */
#line 145 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 36:
-
-/* Line 1806 of yacc.c */
#line 152 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (2)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 37:
-
-/* Line 1806 of yacc.c */
#line 157 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (1)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 38:
-
-/* Line 1806 of yacc.c */
#line 164 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
}
break;
case 39:
-
-/* Line 1806 of yacc.c */
#line 169 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(1) - (1)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
}
break;
case 40:
-
-/* Line 1806 of yacc.c */
#line 176 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
}
break;
case 41:
-
-/* Line 1806 of yacc.c */
#line 181 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(1) - (1)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
}
break;
case 42:
-
-/* Line 1806 of yacc.c */
#line 186 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 43:
-
-/* Line 1806 of yacc.c */
#line 193 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).from.scale = (yyvsp[(3) - (5)].lval);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
}
break;
case 44:
-
-/* Line 1806 of yacc.c */
#line 201 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 45:
-
-/* Line 1806 of yacc.c */
#line 206 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).from.scale = (yyvsp[(3) - (5)].lval);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
}
break;
case 46:
-
-/* Line 1806 of yacc.c */
#line 214 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
}
break;
case 47:
-
-/* Line 1806 of yacc.c */
#line 219 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(1) - (1)].gen);
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(1) - (1)].addr);
}
break;
case 48:
-
-/* Line 1806 of yacc.c */
#line 224 "a.y"
{
- (yyval.gen2).from = nullgen;
- (yyval.gen2).to = (yyvsp[(2) - (2)].gen);
- (yyval.gen2).to.index = (yyvsp[(2) - (2)].gen).type;
- (yyval.gen2).to.type = D_INDIR+D_ADDR;
+ (yyval.addr2).from = nullgen;
+ (yyval.addr2).to = (yyvsp[(2) - (2)].addr);
+ (yyval.addr2).to.index = (yyvsp[(2) - (2)].addr).type;
+ (yyval.addr2).to.type = D_INDIR+D_ADDR;
}
break;
case 51:
-
-/* Line 1806 of yacc.c */
#line 237 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 52:
-
-/* Line 1806 of yacc.c */
#line 242 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (5)].gen);
- if((yyval.gen2).from.index != D_NONE)
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
+ if((yyval.addr2).from.index != D_NONE)
yyerror("dp shift with lhs index");
- (yyval.gen2).from.index = (yyvsp[(5) - (5)].lval);
+ (yyval.addr2).from.index = (yyvsp[(5) - (5)].lval);
}
break;
case 53:
-
-/* Line 1806 of yacc.c */
#line 252 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 54:
-
-/* Line 1806 of yacc.c */
#line 257 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (5)].gen);
- if((yyval.gen2).to.index != D_NONE)
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
+ if((yyval.addr2).to.index != D_NONE)
yyerror("dp move with lhs index");
- (yyval.gen2).to.index = (yyvsp[(5) - (5)].lval);
+ (yyval.addr2).to.index = (yyvsp[(5) - (5)].lval);
}
break;
case 55:
-
-/* Line 1806 of yacc.c */
#line 267 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (2)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (2)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 56:
-
-/* Line 1806 of yacc.c */
#line 272 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (1)].gen);
- (yyval.gen2).to = nullgen;
+ (yyval.addr2).from = (yyvsp[(1) - (1)].addr);
+ (yyval.addr2).to = nullgen;
}
break;
case 57:
-
-/* Line 1806 of yacc.c */
#line 277 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 58:
-
-/* Line 1806 of yacc.c */
#line 284 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 59:
-
-/* Line 1806 of yacc.c */
#line 289 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).from.scale = (yyvsp[(3) - (5)].lval);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).from.scale = (yyvsp[(3) - (5)].lval);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
}
break;
case 60:
-
-/* Line 1806 of yacc.c */
#line 297 "a.y"
{
- (yyval.gen2).from = (yyvsp[(1) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (5)].gen);
- (yyval.gen2).to.offset = (yyvsp[(5) - (5)].lval);
+ (yyval.addr2).from = (yyvsp[(1) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (5)].addr);
+ (yyval.addr2).to.offset = (yyvsp[(5) - (5)].lval);
}
break;
case 61:
-
-/* Line 1806 of yacc.c */
#line 305 "a.y"
{
- (yyval.gen2).from = (yyvsp[(3) - (5)].gen);
- (yyval.gen2).to = (yyvsp[(5) - (5)].gen);
- if((yyvsp[(1) - (5)].gen).type != D_CONST)
+ (yyval.addr2).from = (yyvsp[(3) - (5)].addr);
+ (yyval.addr2).to = (yyvsp[(5) - (5)].addr);
+ if((yyvsp[(1) - (5)].addr).type != D_CONST)
yyerror("illegal constant");
- (yyval.gen2).to.offset = (yyvsp[(1) - (5)].gen).offset;
+ (yyval.addr2).to.offset = (yyvsp[(1) - (5)].addr).offset;
}
break;
case 62:
-
-/* Line 1806 of yacc.c */
#line 315 "a.y"
{
- if((yyvsp[(1) - (3)].gen).type != D_CONST || (yyvsp[(3) - (3)].gen).type != D_CONST)
+ if((yyvsp[(1) - (3)].addr).type != D_CONST || (yyvsp[(3) - (3)].addr).type != D_CONST)
yyerror("arguments to PCDATA must be integer constants");
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 63:
-
-/* Line 1806 of yacc.c */
#line 324 "a.y"
{
- if((yyvsp[(1) - (3)].gen).type != D_CONST)
+ if((yyvsp[(1) - (3)].addr).type != D_CONST)
yyerror("index for FUNCDATA must be integer constant");
- if((yyvsp[(3) - (3)].gen).type != D_EXTERN && (yyvsp[(3) - (3)].gen).type != D_STATIC)
+ if((yyvsp[(3) - (3)].addr).type != D_EXTERN && (yyvsp[(3) - (3)].addr).type != D_STATIC)
yyerror("value for FUNCDATA must be symbol reference");
- (yyval.gen2).from = (yyvsp[(1) - (3)].gen);
- (yyval.gen2).to = (yyvsp[(3) - (3)].gen);
+ (yyval.addr2).from = (yyvsp[(1) - (3)].addr);
+ (yyval.addr2).to = (yyvsp[(3) - (3)].addr);
}
break;
case 68:
-
-/* Line 1806 of yacc.c */
#line 341 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
}
break;
case 69:
-
-/* Line 1806 of yacc.c */
#line 345 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
}
break;
case 75:
-
-/* Line 1806 of yacc.c */
#line 358 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval) + pc;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
}
break;
case 76:
-
-/* Line 1806 of yacc.c */
#line 364 "a.y"
{
- (yyval.gen) = nullgen;
+ (yyval.addr) = nullgen;
if(pass == 2)
yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->name);
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).sym = (yyvsp[(1) - (2)].sym);
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 77:
-
-/* Line 1806 of yacc.c */
-#line 373 "a.y"
+#line 372 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_BRANCH;
- (yyval.gen).sym = (yyvsp[(1) - (2)].sym);
- (yyval.gen).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_BRANCH;
+ (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
}
break;
case 78:
-
-/* Line 1806 of yacc.c */
-#line 382 "a.y"
+#line 380 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 79:
-
-/* Line 1806 of yacc.c */
-#line 387 "a.y"
+#line 385 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 80:
-
-/* Line 1806 of yacc.c */
-#line 392 "a.y"
+#line 390 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 81:
-
-/* Line 1806 of yacc.c */
-#line 397 "a.y"
+#line 395 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 82:
-
-/* Line 1806 of yacc.c */
-#line 402 "a.y"
+#line 400 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SP;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SP;
}
break;
case 83:
-
-/* Line 1806 of yacc.c */
-#line 407 "a.y"
+#line 405 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(1) - (1)].lval);
}
break;
case 84:
-
-/* Line 1806 of yacc.c */
-#line 414 "a.y"
+#line 412 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_CONST;
- (yyval.gen).offset = (yyvsp[(2) - (2)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_CONST;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
}
break;
case 85:
-
-/* Line 1806 of yacc.c */
-#line 420 "a.y"
+#line 418 "a.y"
{
- (yyval.gen) = (yyvsp[(2) - (2)].gen);
- (yyval.gen).index = (yyvsp[(2) - (2)].gen).type;
- (yyval.gen).type = D_ADDR;
+ (yyval.addr) = (yyvsp[(2) - (2)].addr);
+ (yyval.addr).index = (yyvsp[(2) - (2)].addr).type;
+ (yyval.addr).type = D_ADDR;
/*
if($2.type == D_AUTO || $2.type == D_PARAM)
yyerror("constant cannot be automatic: %s",
@@ -2370,76 +2194,62 @@ yyreduce:
break;
case 86:
-
-/* Line 1806 of yacc.c */
-#line 431 "a.y"
+#line 429 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_SCONST;
- memcpy((yyval.gen).sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.gen).sval));
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_SCONST;
+ memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
}
break;
case 87:
-
-/* Line 1806 of yacc.c */
-#line 437 "a.y"
+#line 435 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = (yyvsp[(2) - (2)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
}
break;
case 88:
-
-/* Line 1806 of yacc.c */
-#line 443 "a.y"
+#line 441 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = (yyvsp[(3) - (4)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = (yyvsp[(3) - (4)].dval);
}
break;
case 89:
-
-/* Line 1806 of yacc.c */
-#line 449 "a.y"
+#line 447 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = -(yyvsp[(4) - (5)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = -(yyvsp[(4) - (5)].dval);
}
break;
case 90:
-
-/* Line 1806 of yacc.c */
-#line 455 "a.y"
+#line 453 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_FCONST;
- (yyval.gen).dval = -(yyvsp[(3) - (3)].dval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_FCONST;
+ (yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
}
break;
case 91:
-
-/* Line 1806 of yacc.c */
-#line 463 "a.y"
+#line 461 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_CONST2;
- (yyval.gen).offset = (yyvsp[(2) - (2)].con2).v1;
- (yyval.gen).offset2 = (yyvsp[(2) - (2)].con2).v2;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_CONST2;
+ (yyval.addr).offset = (yyvsp[(2) - (2)].con2).v1;
+ (yyval.addr).offset2 = (yyvsp[(2) - (2)].con2).v2;
}
break;
case 92:
-
-/* Line 1806 of yacc.c */
-#line 472 "a.y"
+#line 470 "a.y"
{
(yyval.con2).v1 = (yyvsp[(1) - (1)].lval);
(yyval.con2).v2 = ArgsSizeUnknown;
@@ -2447,9 +2257,7 @@ yyreduce:
break;
case 93:
-
-/* Line 1806 of yacc.c */
-#line 477 "a.y"
+#line 475 "a.y"
{
(yyval.con2).v1 = -(yyvsp[(2) - (2)].lval);
(yyval.con2).v2 = ArgsSizeUnknown;
@@ -2457,9 +2265,7 @@ yyreduce:
break;
case 94:
-
-/* Line 1806 of yacc.c */
-#line 482 "a.y"
+#line 480 "a.y"
{
(yyval.con2).v1 = (yyvsp[(1) - (3)].lval);
(yyval.con2).v2 = (yyvsp[(3) - (3)].lval);
@@ -2467,9 +2273,7 @@ yyreduce:
break;
case 95:
-
-/* Line 1806 of yacc.c */
-#line 487 "a.y"
+#line 485 "a.y"
{
(yyval.con2).v1 = -(yyvsp[(2) - (4)].lval);
(yyval.con2).v2 = (yyvsp[(4) - (4)].lval);
@@ -2477,370 +2281,290 @@ yyreduce:
break;
case 98:
-
-/* Line 1806 of yacc.c */
-#line 498 "a.y"
+#line 496 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_NONE;
- (yyval.gen).offset = (yyvsp[(1) - (1)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_NONE;
+ (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
}
break;
case 99:
-
-/* Line 1806 of yacc.c */
-#line 504 "a.y"
+#line 502 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (4)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 100:
-
-/* Line 1806 of yacc.c */
-#line 510 "a.y"
+#line 508 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_SP;
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_SP;
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 101:
-
-/* Line 1806 of yacc.c */
-#line 516 "a.y"
+#line 514 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_NONE;
- (yyval.gen).offset = (yyvsp[(1) - (6)].lval);
- (yyval.gen).index = (yyvsp[(3) - (6)].lval);
- (yyval.gen).scale = (yyvsp[(5) - (6)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_NONE;
+ (yyval.addr).offset = (yyvsp[(1) - (6)].lval);
+ (yyval.addr).index = (yyvsp[(3) - (6)].lval);
+ (yyval.addr).scale = (yyvsp[(5) - (6)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 102:
-
-/* Line 1806 of yacc.c */
-#line 525 "a.y"
+#line 523 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (9)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (9)].lval);
- (yyval.gen).index = (yyvsp[(6) - (9)].lval);
- (yyval.gen).scale = (yyvsp[(8) - (9)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (9)].lval);
+ (yyval.addr).index = (yyvsp[(6) - (9)].lval);
+ (yyval.addr).scale = (yyvsp[(8) - (9)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 103:
-
-/* Line 1806 of yacc.c */
-#line 534 "a.y"
+#line 532 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (9)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (9)].lval);
- (yyval.gen).index = (yyvsp[(6) - (9)].lval);
- (yyval.gen).scale = (yyvsp[(8) - (9)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (9)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (9)].lval);
+ (yyval.addr).index = (yyvsp[(6) - (9)].lval);
+ (yyval.addr).scale = (yyvsp[(8) - (9)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 104:
-
-/* Line 1806 of yacc.c */
-#line 543 "a.y"
+#line 541 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(2) - (3)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(2) - (3)].lval);
}
break;
case 105:
-
-/* Line 1806 of yacc.c */
-#line 548 "a.y"
+#line 546 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_SP;
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_SP;
}
break;
case 106:
-
-/* Line 1806 of yacc.c */
-#line 553 "a.y"
+#line 551 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(3) - (4)].lval);
- (yyval.gen).offset = (yyvsp[(1) - (4)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(3) - (4)].lval);
+ (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
}
break;
case 107:
-
-/* Line 1806 of yacc.c */
-#line 559 "a.y"
+#line 557 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+D_NONE;
- (yyval.gen).index = (yyvsp[(2) - (5)].lval);
- (yyval.gen).scale = (yyvsp[(4) - (5)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+D_NONE;
+ (yyval.addr).index = (yyvsp[(2) - (5)].lval);
+ (yyval.addr).scale = (yyvsp[(4) - (5)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 108:
-
-/* Line 1806 of yacc.c */
-#line 567 "a.y"
+#line 565 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_INDIR+(yyvsp[(2) - (8)].lval);
- (yyval.gen).index = (yyvsp[(5) - (8)].lval);
- (yyval.gen).scale = (yyvsp[(7) - (8)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_INDIR+(yyvsp[(2) - (8)].lval);
+ (yyval.addr).index = (yyvsp[(5) - (8)].lval);
+ (yyval.addr).scale = (yyvsp[(7) - (8)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 109:
-
-/* Line 1806 of yacc.c */
-#line 577 "a.y"
+#line 575 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (1)].gen);
+ (yyval.addr) = (yyvsp[(1) - (1)].addr);
}
break;
case 110:
-
-/* Line 1806 of yacc.c */
-#line 581 "a.y"
+#line 579 "a.y"
{
- (yyval.gen) = (yyvsp[(1) - (6)].gen);
- (yyval.gen).index = (yyvsp[(3) - (6)].lval);
- (yyval.gen).scale = (yyvsp[(5) - (6)].lval);
- checkscale((yyval.gen).scale);
+ (yyval.addr) = (yyvsp[(1) - (6)].addr);
+ (yyval.addr).index = (yyvsp[(3) - (6)].lval);
+ (yyval.addr).scale = (yyvsp[(5) - (6)].lval);
+ checkscale((yyval.addr).scale);
}
break;
case 111:
-
-/* Line 1806 of yacc.c */
-#line 590 "a.y"
+#line 588 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = (yyvsp[(4) - (5)].lval);
- (yyval.gen).sym = (yyvsp[(1) - (5)].sym);
- (yyval.gen).offset = (yyvsp[(2) - (5)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = (yyvsp[(4) - (5)].lval);
+ (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
+ (yyval.addr).offset = (yyvsp[(2) - (5)].lval);
}
break;
case 112:
-
-/* Line 1806 of yacc.c */
-#line 597 "a.y"
+#line 595 "a.y"
{
- (yyval.gen) = nullgen;
- (yyval.gen).type = D_STATIC;
- (yyval.gen).sym = (yyvsp[(1) - (7)].sym);
- (yyval.gen).offset = (yyvsp[(4) - (7)].lval);
+ (yyval.addr) = nullgen;
+ (yyval.addr).type = D_STATIC;
+ (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
+ (yyval.addr).offset = (yyvsp[(4) - (7)].lval);
}
break;
case 113:
-
-/* Line 1806 of yacc.c */
-#line 605 "a.y"
+#line 603 "a.y"
{
(yyval.lval) = 0;
}
break;
case 114:
-
-/* Line 1806 of yacc.c */
-#line 609 "a.y"
+#line 607 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 115:
-
-/* Line 1806 of yacc.c */
-#line 613 "a.y"
+#line 611 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 117:
-
-/* Line 1806 of yacc.c */
-#line 620 "a.y"
+#line 618 "a.y"
{
(yyval.lval) = D_AUTO;
}
break;
case 120:
-
-/* Line 1806 of yacc.c */
-#line 628 "a.y"
+#line 626 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
}
break;
case 121:
-
-/* Line 1806 of yacc.c */
-#line 632 "a.y"
+#line 630 "a.y"
{
(yyval.lval) = -(yyvsp[(2) - (2)].lval);
}
break;
case 122:
-
-/* Line 1806 of yacc.c */
-#line 636 "a.y"
+#line 634 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (2)].lval);
}
break;
case 123:
-
-/* Line 1806 of yacc.c */
-#line 640 "a.y"
+#line 638 "a.y"
{
(yyval.lval) = ~(yyvsp[(2) - (2)].lval);
}
break;
case 124:
-
-/* Line 1806 of yacc.c */
-#line 644 "a.y"
+#line 642 "a.y"
{
(yyval.lval) = (yyvsp[(2) - (3)].lval);
}
break;
case 126:
-
-/* Line 1806 of yacc.c */
-#line 651 "a.y"
+#line 649 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
}
break;
case 127:
-
-/* Line 1806 of yacc.c */
-#line 655 "a.y"
+#line 653 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
}
break;
case 128:
-
-/* Line 1806 of yacc.c */
-#line 659 "a.y"
+#line 657 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
}
break;
case 129:
-
-/* Line 1806 of yacc.c */
-#line 663 "a.y"
+#line 661 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
}
break;
case 130:
-
-/* Line 1806 of yacc.c */
-#line 667 "a.y"
+#line 665 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
}
break;
case 131:
-
-/* Line 1806 of yacc.c */
-#line 671 "a.y"
+#line 669 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
}
break;
case 132:
-
-/* Line 1806 of yacc.c */
-#line 675 "a.y"
+#line 673 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
}
break;
case 133:
-
-/* Line 1806 of yacc.c */
-#line 679 "a.y"
+#line 677 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
}
break;
case 134:
-
-/* Line 1806 of yacc.c */
-#line 683 "a.y"
+#line 681 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
}
break;
case 135:
-
-/* Line 1806 of yacc.c */
-#line 687 "a.y"
+#line 685 "a.y"
{
(yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
}
break;
-
-/* Line 1806 of yacc.c */
-#line 2831 "y.tab.c"
+/* Line 1267 of yacc.c. */
+#line 2566 "y.tab.c"
default: break;
}
- /* User semantic actions sometimes alter yychar, and that requires
- that yytoken be updated with the new translation. We take the
- approach of translating immediately before every use of yytoken.
- One alternative is translating here after every semantic action,
- but that translation would be missed if the semantic action invokes
- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
- incorrect destructor might then be invoked immediately. In the
- case of YYERROR or YYBACKUP, subsequent parser actions might lead
- to an incorrect destructor call or verbose syntax error message
- before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@@ -2849,6 +2573,7 @@ yyreduce:
*++yyvsp = yyval;
+
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
@@ -2868,10 +2593,6 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -2879,36 +2600,37 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
- yyssp, yytoken)
{
- char const *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = YYSYNTAX_ERROR;
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == 1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
- if (!yymsg)
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = 2;
- }
- else
- {
- yysyntax_error_status = YYSYNTAX_ERROR;
- yymsgp = yymsg;
- }
- }
- yyerror (yymsgp);
- if (yysyntax_error_status == 2)
- goto yyexhaustedlab;
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
}
-# undef YYSYNTAX_ERROR
#endif
}
@@ -2916,7 +2638,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
@@ -2933,7 +2655,7 @@ yyerrlab:
}
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
@@ -2967,7 +2689,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
- if (!yypact_value_is_default (yyn))
+ if (yyn != YYPACT_NINF)
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -2990,6 +2712,9 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
*++yyvsp = yylval;
@@ -3014,7 +2739,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -3025,14 +2750,9 @@ yyexhaustedlab:
#endif
yyreturn:
- if (yychar != YYEMPTY)
- {
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = YYTRANSLATE (yychar);
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- }
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
diff --git a/src/cmd/8a/y.tab.h b/src/cmd/8a/y.tab.h
index 14637cb33..d19145548 100644
--- a/src/cmd/8a/y.tab.h
+++ b/src/cmd/8a/y.tab.h
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison interface for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -112,11 +114,8 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c */
#line 38 "a.y"
-
+{
Sym *sym;
int32 lval;
struct {
@@ -125,19 +124,16 @@ typedef union YYSTYPE
} con2;
double dval;
char sval[8];
- Gen gen;
- Gen2 gen2;
-
-
-
-/* Line 2068 of yacc.c */
-#line 135 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+ Addr addr;
+ Addr2 addr2;
+}
+/* Line 1529 of yacc.c. */
+#line 132 "y.tab.h"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
-
diff --git a/src/cmd/8c/gc.h b/src/cmd/8c/gc.h
index b668b4c63..87b8e22bc 100644
--- a/src/cmd/8c/gc.h
+++ b/src/cmd/8c/gc.h
@@ -46,11 +46,8 @@
#define SZ_DOUBLE 8
#define FNX 100
-typedef struct Adr Adr;
-typedef struct Prog Prog;
typedef struct Case Case;
typedef struct C1 C1;
-typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
typedef struct Renv Renv;
@@ -64,30 +61,10 @@ EXTERN struct
short ptr;
} idx;
-struct Adr
-{
- int32 offset;
- int32 offset2;
- double dval;
- char sval[NSNAME];
-
- Sym* sym;
- uchar type;
- uchar index;
- uchar etype;
- uchar scale; /* doubles as width in DATA op */
-};
-#define A ((Adr*)0)
+#define A ((Addr*)0)
#define INDEXED 9
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* link;
- int32 lineno;
- short as;
-};
+
#define P ((Prog*)0)
struct Case
@@ -106,14 +83,6 @@ struct C1
int32 label;
};
-struct Var
-{
- int32 offset;
- Sym* sym;
- char name;
- char etype;
-};
-
struct Reg
{
int32 pc;
@@ -171,7 +140,6 @@ EXTERN Node fconstnode;
EXTERN int32 continpc;
EXTERN int32 curarg;
EXTERN int32 cursafe;
-EXTERN Prog* firstp;
EXTERN Prog* lastp;
EXTERN int32 maxargsafe;
EXTERN int mnstring;
@@ -226,7 +194,6 @@ EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
-EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
@@ -287,7 +254,7 @@ void regaalloc1(Node*, Node*);
void regaalloc(Node*, Node*);
void regind(Node*, Node*);
void gprep(Node*, Node*);
-void naddr(Node*, Adr*);
+void naddr(Node*, Addr*);
void gmove(Node*, Node*);
void gins(int a, Node*, Node*);
void fgopcode(int, Node*, Node*, int, int);
@@ -315,19 +282,11 @@ void nullwarn(Node*, Node*);
void sextern(Sym*, Node*, int32, int32);
void gextern(Sym*, Node*, int32, int32);
void outcode(void);
-void ieeedtod(Ieee*, double);
/*
* list
*/
void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Rconv(Fmt*);
-int Xconv(Fmt*);
-int Bconv(Fmt*);
/*
* reg.c
@@ -336,7 +295,7 @@ Reg* rega(void);
int rcmp(const void*, const void*);
void regopt(Prog*);
void addmove(Reg*, int, int, int);
-Bits mkvar(Reg*, Adr*);
+Bits mkvar(Reg*, Addr*);
void prop(Reg*, Bits, Bits);
void loopit(Reg*, int32);
void synch(Reg*, Bits);
@@ -344,7 +303,7 @@ uint32 allreg(uint32, Rgn*);
void paint1(Reg*, int);
uint32 paint2(Reg*, int);
void paint3(Reg*, int, int32, int);
-void addreg(Adr*, int);
+void addreg(Addr*, int);
/*
* peep.c
@@ -353,17 +312,17 @@ void peep(void);
void excise(Reg*);
Reg* uniqp(Reg*);
Reg* uniqs(Reg*);
-int regtyp(Adr*);
-int anyvar(Adr*);
+int regtyp(Addr*);
+int anyvar(Addr*);
int subprop(Reg*);
int copyprop(Reg*);
-int copy1(Adr*, Adr*, Reg*, int);
-int copyu(Prog*, Adr*, Adr*);
+int copy1(Addr*, Addr*, Reg*, int);
+int copyu(Prog*, Addr*, Addr*);
-int copyas(Adr*, Adr*);
-int copyau(Adr*, Adr*);
-int copysub(Adr*, Adr*, Adr*, int);
-int copysub1(Prog*, Adr*, Adr*, int);
+int copyas(Addr*, Addr*);
+int copyau(Addr*, Addr*);
+int copysub(Addr*, Addr*, Addr*, int);
+int copysub1(Prog*, Addr*, Addr*, int);
int32 RtoB(int);
int32 FtoB(int);
@@ -401,14 +360,6 @@ void mulgen(Type*, Node*, Node*);
void genmuladd(Node*, Node*, int, Node*);
void shiftit(Type*, Node*, Node*);
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Adr*
-#pragma varargck type "lD" Adr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-
/* wrecklessly steal a field */
#define rplink label
diff --git a/src/cmd/8c/list.c b/src/cmd/8c/list.c
index 8506e08ef..1730eccd0 100644
--- a/src/cmd/8c/list.c
+++ b/src/cmd/8c/list.c
@@ -34,319 +34,5 @@
void
listinit(void)
{
-
- fmtinstall('A', Aconv);
- fmtinstall('B', Bconv);
- fmtinstall('P', Pconv);
- fmtinstall('S', Sconv);
- fmtinstall('D', Dconv);
- fmtinstall('R', Rconv);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == S) {
- sprint(ss, "$%d", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- switch(p->as) {
- case ADATA:
- sprint(str, "(%L) %A %D/%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
-
- case ATEXT:
- if(p->from.scale) {
- sprint(str, "(%L) %A %D,%d,%lD",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- sprint(str, "(%L) %A %D,%lD",
- p->lineno, p->as, &p->from, &p->to);
- break;
-
- default:
- sprint(str, "(%L) %A %D,%D",
- p->lineno, p->as, &p->from, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Adr *a;
- int i;
-
- a = va_arg(fp->args, Adr*);
- i = a->type;
-
- if(fp->flags & FmtLong) {
- if(i == D_CONST2)
- sprint(str, "$%d-%d", a->offset, a->offset2);
- else {
- // ATEXT dst is not constant
- sprint(str, "!!%D", a);
- }
- goto brk;
- }
-
- if(i >= D_INDIR) {
- if(a->offset)
- sprint(str, "%d(%R)", a->offset, i-D_INDIR);
- else
- sprint(str, "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
- default:
- if(a->offset)
- sprint(str, "$%d,%R", a->offset, i);
- else
- sprint(str, "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- sprint(str, "%d", a->offset);
- break;
-
- case D_EXTERN:
- sprint(str, "%s+%d(SB)", a->sym->name, a->offset);
- break;
-
- case D_STATIC:
- sprint(str, "%s<>+%d(SB)", a->sym->name, a->offset);
- break;
-
- case D_AUTO:
- if(a->sym)
- sprint(str, "%s+%d(SP)", a->sym->name, a->offset);
- else
- sprint(str, "%d(SP)", a->offset);
- break;
-
- case D_PARAM:
- if(a->sym)
- sprint(str, "%s+%d(FP)", a->sym->name, a->offset);
- else
- sprint(str, "%d(FP)", a->offset);
- break;
-
- case D_CONST:
- sprint(str, "$%d", a->offset);
- break;
-
- case D_CONST2:
- if(!(fp->flags & FmtLong)) {
- // D_CONST2 outside of ATEXT should not happen
- sprint(str, "!!$%d-%d", a->offset, a->offset2);
- }
- break;
-
- case D_FCONST:
- sprint(str, "$(%.17e)", a->dval);
- break;
-
- case D_SCONST:
- sprint(str, "$\"%S\"", a->sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- sprint(str, "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
- }
-conv:
- return fmtstrcpy(fp, str);
-}
-
-char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
- "AH",
- "CH",
- "DH",
- "BH",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "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",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "X0", /* [D_X0] */
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_AL && r <= D_NONE)
- sprint(str, "%s", regstr[r-D_AL]);
- else
- sprint(str, "gok(%d)", r);
-
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(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);
+ listinit8();
}
diff --git a/src/cmd/8c/peep.c b/src/cmd/8c/peep.c
index da0127d11..4f58fc05c 100644
--- a/src/cmd/8c/peep.c
+++ b/src/cmd/8c/peep.c
@@ -217,7 +217,7 @@ uniqs(Reg *r)
}
int
-regtyp(Adr *a)
+regtyp(Addr *a)
{
int t;
@@ -245,7 +245,7 @@ int
subprop(Reg *r0)
{
Prog *p;
- Adr *v1, *v2;
+ Addr *v1, *v2;
Reg *r;
int t;
@@ -365,7 +365,7 @@ int
copyprop(Reg *r0)
{
Prog *p;
- Adr *v1, *v2;
+ Addr *v1, *v2;
Reg *r;
p = r0->prog;
@@ -379,7 +379,7 @@ copyprop(Reg *r0)
}
int
-copy1(Adr *v1, Adr *v2, Reg *r, int f)
+copy1(Addr *v1, Addr *v2, Reg *r, int f)
{
int t;
Prog *p;
@@ -464,7 +464,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f)
* 0 otherwise (not touched)
*/
int
-copyu(Prog *p, Adr *v, Adr *s)
+copyu(Prog *p, Addr *v, Addr *s)
{
switch(p->as) {
@@ -740,7 +740,7 @@ copyu(Prog *p, Adr *v, Adr *s)
* semantics
*/
int
-copyas(Adr *a, Adr *v)
+copyas(Addr *a, Addr *v)
{
if(a->type != v->type)
return 0;
@@ -756,7 +756,7 @@ copyas(Adr *a, Adr *v)
* either direct or indirect
*/
int
-copyau(Adr *a, Adr *v)
+copyau(Addr *a, Addr *v)
{
if(copyas(a, v))
@@ -775,7 +775,7 @@ copyau(Adr *a, Adr *v)
* return failure to substitute
*/
int
-copysub(Adr *a, Adr *v, Adr *s, int f)
+copysub(Addr *a, Addr *v, Addr *s, int f)
{
int t;
diff --git a/src/cmd/8c/reg.c b/src/cmd/8c/reg.c
index a3d5d6115..e6ba8bcb3 100644
--- a/src/cmd/8c/reg.c
+++ b/src/cmd/8c/reg.c
@@ -558,7 +558,7 @@ brk:
if(debug['R'] && debug['v']) {
print("after pass 7 (peep)\n");
for(r=firstr; r; r=r->link)
- print("%04d %P\n", r->pc, r->prog);
+ print("%04d %P\n", (int)r->pc, r->prog);
print("\n");
}
@@ -602,8 +602,10 @@ brk:
r1 = 0; /* set */
for(r = firstr; r != R; r = r->link) {
p = r->prog;
- if(p->to.type == D_BRANCH)
+ if(p->to.type == D_BRANCH) {
p->to.offset = r->s2->pc;
+ p->to.u.branch = r->s2->prog;
+ }
r1 = r;
}
@@ -638,7 +640,7 @@ void
addmove(Reg *r, int bn, int rn, int f)
{
Prog *p, *p1;
- Adr *a;
+ Addr *a;
Var *v;
p1 = alloc(sizeof(*p1));
@@ -697,13 +699,13 @@ doregbits(int r)
}
Bits
-mkvar(Reg *r, Adr *a)
+mkvar(Reg *r, Addr *a)
{
Var *v;
int i, t, n, et, z;
int32 o;
Bits bit;
- Sym *s;
+ LSym *s;
/*
* mark registers used
@@ -730,7 +732,7 @@ mkvar(Reg *r, Adr *a)
break;
}
s = a->sym;
- if(s == S)
+ if(s == nil)
goto none;
if(s->name[0] == '.')
goto none;
@@ -1121,7 +1123,7 @@ uint32
regset(Reg *r, uint32 bb)
{
uint32 b, set;
- Adr v;
+ Addr v;
int c;
set = 0;
@@ -1140,7 +1142,7 @@ uint32
reguse(Reg *r, uint32 bb)
{
uint32 b, set;
- Adr v;
+ Addr v;
int c;
set = 0;
@@ -1287,7 +1289,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
}
void
-addreg(Adr *a, int rn)
+addreg(Addr *a, int rn)
{
a->sym = 0;
@@ -1373,10 +1375,11 @@ fixjmp(Reg *firstr)
for(r=firstr; r; r=r->link) {
p = r->prog;
if(debug['R'] && debug['v'])
- print("%04d %P\n", r->pc, p);
+ print("%04d %P\n", (int)r->pc, p);
if(p->as != ACALL && p->to.type == D_BRANCH && r->s2 && r->s2->prog->as == AJMP) {
r->s2 = chasejmp(r->s2, &jmploop);
p->to.offset = r->s2->pc;
+ p->to.u.branch = r->s2->prog;
if(debug['R'] && debug['v'])
print("->%P\n", p);
}
@@ -1397,7 +1400,7 @@ fixjmp(Reg *firstr)
// Let it stay.
} else {
if(debug['R'] && debug['v'])
- print("del %04d %P\n", r->pc, p);
+ print("del %04d %P\n", (int)r->pc, p);
p->as = ANOP;
}
}
@@ -1410,7 +1413,7 @@ fixjmp(Reg *firstr)
p = r->prog;
if(p->as == AJMP && p->to.type == D_BRANCH && r->s2 == r->link) {
if(debug['R'] && debug['v'])
- print("del %04d %P\n", r->pc, p);
+ print("del %04d %P\n", (int)r->pc, p);
p->as = ANOP;
}
}
@@ -1431,7 +1434,7 @@ fixjmp(Reg *firstr)
if(debug['R'] && debug['v']) {
print("\n");
for(r=firstr; r; r=r->link)
- print("%04d %P\n", r->pc, r->prog);
+ print("%04d %P\n", (int)r->pc, r->prog);
print("\n");
}
}
diff --git a/src/cmd/8c/swt.c b/src/cmd/8c/swt.c
index b68197447..ae36f84ea 100644
--- a/src/cmd/8c/swt.c
+++ b/src/cmd/8c/swt.c
@@ -169,7 +169,7 @@ outstring(char *s, int32 n)
p->from.offset += nstring - NSNAME;
p->from.scale = NSNAME;
p->to.type = D_SCONST;
- memmove(p->to.sval, string, NSNAME);
+ memmove(p->to.u.sval, string, NSNAME);
mnstring = 0;
}
n--;
@@ -190,7 +190,7 @@ sextern(Sym *s, Node *a, int32 o, int32 w)
p->from.offset += o+e;
p->from.scale = lw;
p->to.type = D_SCONST;
- memmove(p->to.sval, a->cstring+e, lw);
+ memmove(p->to.u.sval, a->cstring+e, lw);
}
}
@@ -220,29 +220,12 @@ gextern(Sym *s, Node *a, int32 o, int32 w)
}
}
-void zname(Biobuf*, Sym*, int);
-void zaddr(Biobuf*, Adr*, int);
-void outhist(Biobuf*);
-
void
outcode(void)
{
- struct { Sym *sym; short type; } h[NSYM];
- Prog *p;
- Sym *s;
- int f, sf, st, t, sym;
+ int f;
Biobuf b;
- if(debug['S']) {
- for(p = firstp; p != P; p = p->link)
- if(p->as != ADATA && p->as != AGLOBL)
- pc--;
- for(p = firstp; p != P; p = p->link) {
- print("%P\n", p);
- if(p->as != ADATA && p->as != AGLOBL)
- pc++;
- }
- }
f = open(outfile, OWRITE);
if(f < 0) {
diag(Z, "cannot open %s", outfile);
@@ -250,7 +233,7 @@ outcode(void)
}
Binit(&b, f, OWRITE);
- Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
+ Bprint(&b, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
if(pragcgobuf.to > pragcgobuf.start) {
Bprint(&b, "\n");
Bprint(&b, "$$ // exports\n\n");
@@ -261,258 +244,12 @@ outcode(void)
}
Bprint(&b, "!\n");
- outhist(&b);
- for(sym=0; sym<NSYM; sym++) {
- h[sym].sym = S;
- h[sym].type = 0;
- }
- sym = 1;
- for(p = firstp; p != P; p = p->link) {
- jackpot:
- sf = 0;
- s = p->from.sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = p->from.type;
- if(t == D_ADDR)
- t = p->from.index;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- s->sym = sym;
- zname(&b, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = p->to.sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = p->to.type;
- if(t == D_ADDR)
- t = p->to.index;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- s->sym = sym;
- zname(&b, s, t);
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- BPUTLE2(&b, p->as);
- BPUTLE4(&b, p->lineno);
- zaddr(&b, &p->from, sf);
- zaddr(&b, &p->to, st);
- }
+ writeobj(ctxt, &b);
Bterm(&b);
close(f);
- firstp = P;
lastp = P;
}
-void
-outhist(Biobuf *b)
-{
- Hist *h;
- char *p, *q, *op, c;
- Prog pg;
- int n;
- char *tofree;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
- pg = zprog;
- pg.as = AHISTORY;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p != nil && goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- op = 0;
- if(systemtype(Windows) && p && p[1] == ':'){
- c = p[2];
- } else if(p && p[0] != c && h->offset == 0 && pathname){
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname;
- c = p[2];
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = utfrune(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- BPUTLE2(b, ANAME);
- BPUTC(b, D_FILE);
- BPUTC(b, 1);
- BPUTC(b, '<');
- Bwrite(b, p, n);
- BPUTC(b, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- pg.lineno = h->line;
- pg.to.type = zprog.to.type;
- pg.to.offset = h->offset;
- if(h->offset)
- pg.to.type = D_CONST;
-
- BPUTLE2(b, pg.as);
- BPUTLE4(b, pg.lineno);
- zaddr(b, &pg.from, 0);
- zaddr(b, &pg.to, 0);
-
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- char *n;
- uint32 sig;
-
- if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
- sig = sign(s);
- BPUTLE2(b, ASIGNAME);
- BPUTLE4(b, sig);
- s->sig = SIGDONE;
- }
- else{
- BPUTLE2(b, ANAME); /* as */
- }
- BPUTC(b, t); /* type */
- BPUTC(b, s->sym); /* sym */
- n = s->name;
- while(*n) {
- BPUTC(b, *n);
- n++;
- }
- BPUTC(b, 0);
-}
-
-void
-zaddr(Biobuf *b, Adr *a, int s)
-{
- int32 l;
- int i, t;
- char *n;
- Ieee e;
-
- t = 0;
- if(a->index != D_NONE || a->scale != 0)
- t |= T_INDEX;
- if(s != 0)
- t |= T_SYM;
-
- switch(a->type) {
- default:
- t |= T_TYPE;
- case D_NONE:
- if(a->offset != 0)
- t |= T_OFFSET;
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- case D_CONST2:
- t |= T_OFFSET|T_OFFSET2;
- break;
- }
- BPUTC(b, t);
-
- if(t & T_INDEX) { /* implies index, scale */
- BPUTC(b, a->index);
- BPUTC(b, a->scale);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- BPUTLE4(b, l);
- }
- if(t & T_OFFSET2) { /* implies offset2 */
- l = a->offset2;
- BPUTLE4(b, l);
- }
- if(t & T_SYM) /* implies sym */
- BPUTC(b, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->dval);
- BPUTLE4(b, e.l);
- BPUTLE4(b, e.h);
- return;
- }
- if(t & T_SCONST) {
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(b, *n);
- n++;
- }
- return;
- }
- if(t & T_TYPE)
- BPUTC(b, a->type);
-}
-
int32
align(int32 i, Type *t, int op, int32 *maxalign)
{
diff --git a/src/cmd/8c/txt.c b/src/cmd/8c/txt.c
index 5c486af38..25082de05 100644
--- a/src/cmd/8c/txt.c
+++ b/src/cmd/8c/txt.c
@@ -30,14 +30,23 @@
#include "gc.h"
+
+int thechar = '8';
+char *thestring = "386";
+
+LinkArch *thelinkarch = &link386;
+
+void
+linkarchinit(void)
+{
+}
+
void
ginit(void)
{
int i;
Type *t;
- thechar = '8';
- thestring = "386";
exregoffset = 0;
exfregoffset = 0;
listinit();
@@ -48,7 +57,6 @@ ginit(void)
breakpc = -1;
continpc = -1;
cases = C;
- firstp = P;
lastp = P;
tfield = types[TLONG];
@@ -156,17 +164,18 @@ gclean(void)
void
nextpc(void)
{
+ Plist *pl;
p = alloc(sizeof(*p));
*p = zprog;
p->lineno = nearln;
+ p->pc = pc;
pc++;
- if(firstp == P) {
- firstp = p;
- lastp = p;
- return;
- }
- lastp->link = p;
+ if(lastp == nil) {
+ pl = linknewplist(ctxt);
+ pl->firstpc = p;
+ } else
+ lastp->link = p;
lastp = p;
}
@@ -188,7 +197,8 @@ gargs(Node *n, Node *tn1, Node *tn2)
cursafe = regs;
}
-int nareg(void)
+int
+nareg(void)
{
int i, n;
@@ -435,7 +445,7 @@ regind(Node *n, Node *nn)
}
void
-naddr(Node *n, Adr *a)
+naddr(Node *n, Addr *a)
{
int32 v;
@@ -450,11 +460,11 @@ naddr(Node *n, Adr *a)
case OREGISTER:
a->type = n->reg;
- a->sym = S;
+ a->sym = nil;
break;
case OEXREG:
- a->type = D_INDIR + D_GS;
+ a->type = D_INDIR + D_TLS;
a->offset = n->reg - 1;
break;
@@ -495,14 +505,14 @@ naddr(Node *n, Adr *a)
case OINDREG:
a->type = n->reg+D_INDIR;
- a->sym = S;
+ a->sym = nil;
a->offset = n->xoffset;
break;
case ONAME:
a->etype = n->etype;
a->type = D_STATIC;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
a->offset = n->xoffset;
if(n->class == CSTATIC)
break;
@@ -523,10 +533,10 @@ naddr(Node *n, Adr *a)
case OCONST:
if(typefd[n->type->etype]) {
a->type = D_FCONST;
- a->dval = n->fconst;
+ a->u.dval = n->fconst;
break;
}
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = n->vconst;
break;
@@ -1366,9 +1376,10 @@ gbranch(int o)
void
patch(Prog *op, int32 pc)
{
-
op->to.offset = pc;
op->to.type = D_BRANCH;
+ op->to.u.branch = nil;
+ op->pcond = nil;
}
void
@@ -1378,7 +1389,7 @@ gpseudo(int a, Sym *s, Node *n)
nextpc();
p->as = a;
p->from.type = D_EXTERN;
- p->from.sym = s;
+ p->from.sym = linksym(s);
switch(a) {
case ATEXT:
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index cc28a3145..d626c2eb0 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -242,6 +242,7 @@ cgen(Node *n, Node *res)
case OOR:
case OXOR:
case OADD:
+ case OADDPTR:
case OMUL:
a = optoas(n->op, nl->type);
if(a == AIMULB) {
@@ -522,6 +523,7 @@ agen(Node *n, Node *res)
// The generated code is just going to panic, so it need not
// be terribly efficient. See issue 3670.
tempname(&n1, n->type);
+ gvardef(&n1);
clearfat(&n1);
regalloc(&n2, types[tptr], res);
gins(ALEAL, &n1, &n2);
@@ -934,6 +936,13 @@ bgen(Node *n, int true, int likely, Prog *to)
patch(gins(AEND, N, N), to);
return;
}
+
+ while(n->op == OCONVNOP) {
+ n = n->left;
+ if(n->ninit != nil)
+ genlist(n->ninit);
+ }
+
nl = n->left;
nr = N;
@@ -1203,6 +1212,8 @@ sgen(Node *n, Node *res, int64 w)
{
Node dst, src, tdst, tsrc;
int32 c, q, odst, osrc;
+ NodeList *l;
+ Prog *p;
if(debug['g']) {
print("\nsgen w=%lld\n", w);
@@ -1223,6 +1234,13 @@ sgen(Node *n, Node *res, int64 w)
return;
}
+ // If copying .args, that's all the results, so record definition sites
+ // for them for the liveness analysis.
+ if(res->op == ONAME && strcmp(res->sym->name, ".args") == 0)
+ for(l = curfn->dcl; l != nil; l = l->next)
+ if(l->n->class == PPARAMOUT)
+ gvardef(l->n);
+
// Avoid taking the address for simple enough types.
if(componentgen(n, res))
return;
@@ -1255,6 +1273,10 @@ sgen(Node *n, Node *res, int64 w)
agen(n, &src);
else
gmove(&tsrc, &src);
+
+ if(res->op == ONAME)
+ gvardef(res);
+
if(res->addable)
agen(res, &dst);
else
@@ -1294,10 +1316,16 @@ sgen(Node *n, Node *res, int64 w)
} else {
gins(ACLD, N, N); // paranoia. TODO(rsc): remove?
// normal direction
- if(q >= 4) {
+ if(q > 128 || (q >= 4 && nacl)) {
gconreg(AMOVL, q, D_CX);
gins(AREP, N, N); // repeat
gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
+ } else if(q >= 4) {
+ p = gins(ADUFFCOPY, N, N);
+ p->to.type = D_ADDR;
+ p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
+ // 10 and 128 = magic constants: see ../../pkg/runtime/asm_386.s
+ p->to.offset = 10*(128-q);
} else
while(q > 0) {
gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
@@ -1369,8 +1397,17 @@ componentgen(Node *nr, Node *nl)
}
}
+ // nl and nr are 'cadable' which basically means they are names (variables) now.
+ // If they are the same variable, don't generate any code, because the
+ // VARDEF we generate will mark the old value as dead incorrectly.
+ // (And also the assignments are useless.)
+ if(nr != N && nl->op == ONAME && nr->op == ONAME && nl == nr)
+ goto yes;
+
switch(nl->type->etype) {
case TARRAY:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(nl->type->type);
@@ -1404,6 +1441,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TSTRING:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
@@ -1427,6 +1466,8 @@ componentgen(Node *nr, Node *nl)
goto yes;
case TINTER:
+ if(nl->op == ONAME)
+ gvardef(nl);
nodl.xoffset += Array_array;
nodl.type = ptrto(types[TUINT8]);
diff --git a/src/cmd/8g/galign.c b/src/cmd/8g/galign.c
index 2c8aaa0a4..fbd2e9ad3 100644
--- a/src/cmd/8g/galign.c
+++ b/src/cmd/8g/galign.c
@@ -8,6 +8,12 @@
int thechar = '8';
char* thestring = "386";
+LinkArch* thelinkarch = &link386;
+
+void
+linkarchinit(void)
+{
+}
vlong MAXWIDTH = (1LL<<32) - 1;
@@ -28,6 +34,7 @@ betypeinit(void)
{
widthptr = 4;
widthint = 4;
+ widthreg = 4;
zprog.link = P;
zprog.as = AGOK;
@@ -36,5 +43,5 @@ betypeinit(void)
zprog.from.scale = 0;
zprog.to = zprog.from;
- listinit();
+ listinit8();
}
diff --git a/src/cmd/8g/gg.h b/src/cmd/8g/gg.h
index 55fdded0b..bdefa93b5 100644
--- a/src/cmd/8g/gg.h
+++ b/src/cmd/8g/gg.h
@@ -9,42 +9,6 @@
#include "../gc/go.h"
#include "../8l/8.out.h"
-typedef struct Addr Addr;
-
-struct Addr
-{
- int32 offset;
- int32 offset2;
-
- union {
- double dval;
- vlong vval;
- Prog* branch;
- char sval[NSNAME];
- } u;
-
- Sym* gotype;
- Sym* sym;
- Node* node;
- int width;
- uchar type;
- uchar index;
- uchar etype;
- uchar scale; /* doubles as width in DATA op */
-};
-#define A ((Addr*)0)
-
-struct Prog
-{
- short as; // opcode
- uint32 loc; // pc offset in this func
- uint32 lineno; // source line that generated this
- Addr from; // src address
- Addr to; // dst address
- Prog* link; // next instruction in this func
- void* opt; // for optimizer passes
-};
-
#define TEXTFLAG from.scale
// foptoas flags
@@ -59,15 +23,14 @@ EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE];
EXTERN int32 pcloc; // instruction counter
EXTERN Strlit emptystring;
-extern char* anames[];
EXTERN Prog zprog;
EXTERN Node* newproc;
EXTERN Node* deferproc;
EXTERN Node* deferreturn;
EXTERN Node* panicindex;
EXTERN Node* panicslice;
+EXTERN Node* panicdiv;
EXTERN Node* throwreturn;
-EXTERN int maxstksize;
extern uint32 unmappedzero;
@@ -168,14 +131,6 @@ void datagostring(Strlit*, Addr*);
/*
* list.c
*/
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Yconv(Fmt*);
void listinit(void);
void zaddr(Biobuf*, Addr*, int, int);
-
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index fa5ed00dd..2285a04e6 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -9,61 +9,100 @@
#include "gg.h"
#include "opt.h"
-static Prog* appendp(Prog*, int, int, int32, int, int32);
+static Prog *appendpp(Prog*, int, int, vlong, int, vlong);
+static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax);
void
-defframe(Prog *ptxt, Bvec *bv)
+defframe(Prog *ptxt)
{
- uint32 frame;
+ uint32 frame, ax;
Prog *p;
- int i, j;
+ vlong lo, hi;
+ NodeList *l;
+ Node *n;
// fill in argument size
ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
- if(stksize > maxstksize)
- maxstksize = stksize;
- frame = rnd(maxstksize+maxarg, widthptr);
+ frame = rnd(stksize+maxarg, widthptr);
ptxt->to.offset = frame;
- maxstksize = 0;
-
- // insert code to clear pointered part of the frame,
- // so that garbage collector only sees initialized values
+
+ // insert code to zero ambiguously live variables
+ // so that the garbage collector only sees initialized values
// when it looks for pointers.
p = ptxt;
- if(stkzerosize >= 8*widthptr) {
- p = appendp(p, AMOVL, D_CONST, 0, D_AX, 0);
- p = appendp(p, AMOVL, D_CONST, stkzerosize/widthptr, D_CX, 0);
- p = appendp(p, ALEAL, D_SP+D_INDIR, frame-stkzerosize, D_DI, 0);
- p = appendp(p, AREP, D_NONE, 0, D_NONE, 0);
- appendp(p, ASTOSL, D_NONE, 0, D_NONE, 0);
- } else {
- j = (stkptrsize - stkzerosize)/widthptr * 2;
- for(i=0; i<stkzerosize; i+=widthptr) {
- if(bvget(bv, j) || bvget(bv, j+1))
- p = appendp(p, AMOVL, D_CONST, 0, D_SP+D_INDIR, frame-stkzerosize+i);
- j += 2;
+ hi = 0;
+ lo = hi;
+ ax = 0;
+ for(l=curfn->dcl; l != nil; l = l->next) {
+ n = l->n;
+ if(!n->needzero)
+ continue;
+ if(n->class != PAUTO)
+ fatal("needzero class %d", n->class);
+ if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
+ fatal("var %lN has size %d offset %d", n, (int)n->type->width, (int)n->xoffset);
+ if(lo != hi && n->xoffset + n->type->width == lo - 2*widthptr) {
+ // merge with range we already have
+ lo = n->xoffset;
+ continue;
}
+ // zero old range
+ p = zerorange(p, frame, lo, hi, &ax);
+
+ // set new range
+ hi = n->xoffset + n->type->width;
+ lo = n->xoffset;
}
+ // zero final range
+ zerorange(p, frame, lo, hi, &ax);
}
static Prog*
-appendp(Prog *p, int as, int ftype, int32 foffset, int ttype, int32 toffset)
+zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *ax)
+{
+ vlong cnt, i;
+
+ cnt = hi - lo;
+ if(cnt == 0)
+ return p;
+ if(*ax == 0) {
+ p = appendpp(p, AMOVL, D_CONST, 0, D_AX, 0);
+ *ax = 1;
+ }
+ if(cnt <= 4*widthreg) {
+ for(i = 0; i < cnt; i += widthreg) {
+ p = appendpp(p, AMOVL, D_AX, 0, D_SP+D_INDIR, frame+lo+i);
+ }
+ } else if(!nacl && cnt <= 128*widthreg) {
+ p = appendpp(p, ALEAL, D_SP+D_INDIR, frame+lo, D_DI, 0);
+ p = appendpp(p, ADUFFZERO, D_NONE, 0, D_ADDR, 1*(128-cnt/widthreg));
+ p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
+ } else {
+ p = appendpp(p, AMOVL, D_CONST, cnt/widthreg, D_CX, 0);
+ p = appendpp(p, ALEAL, D_SP+D_INDIR, frame+lo, D_DI, 0);
+ p = appendpp(p, AREP, D_NONE, 0, D_NONE, 0);
+ p = appendpp(p, ASTOSL, D_NONE, 0, D_NONE, 0);
+ }
+ return p;
+}
+
+static Prog*
+appendpp(Prog *p, int as, int ftype, vlong foffset, int ttype, vlong toffset)
{
Prog *q;
-
- q = mal(sizeof(*q));
- clearp(q);
- q->as = as;
- q->lineno = p->lineno;
- q->from.type = ftype;
- q->from.offset = foffset;
- q->to.type = ttype;
- q->to.offset = toffset;
- q->link = p->link;
- p->link = q;
- return q;
+ q = mal(sizeof(*q));
+ clearp(q);
+ q->as = as;
+ q->lineno = p->lineno;
+ q->from.type = ftype;
+ q->from.offset = foffset;
+ q->to.type = ttype;
+ q->to.offset = toffset;
+ q->link = p->link;
+ p->link = q;
+ return q;
}
// Sweep the prog list to mark any used nodes.
@@ -71,13 +110,13 @@ void
markautoused(Prog* p)
{
for (; p; p = p->link) {
- if (p->as == ATYPE)
+ if (p->as == ATYPE || p->as == AVARDEF || p->as == AVARKILL)
continue;
- if (p->from.type == D_AUTO && p->from.node)
+ if (p->from.node)
p->from.node->used = 1;
- if (p->to.type == D_AUTO && p->to.node)
+ if (p->to.node)
p->to.node->used = 1;
}
}
@@ -93,6 +132,16 @@ fixautoused(Prog* p)
*lp = p->link;
continue;
}
+ if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) {
+ // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
+ // VARDEFs are interspersed with other code, and a jump might be using the
+ // VARDEF as a target. Replace with a no-op instead. A later pass will remove
+ // the no-ops.
+ p->to.type = D_NONE;
+ p->to.node = N;
+ p->as = ANOP;
+ continue;
+ }
if (p->from.type == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta;
@@ -109,6 +158,7 @@ clearfat(Node *nl)
{
uint32 w, c, q;
Node n1;
+ Prog *p;
/* clear a fat object */
if(debug['g'])
@@ -126,21 +176,22 @@ clearfat(Node *nl)
agen(nl, &n1);
gconreg(AMOVL, 0, D_AX);
- if(q >= 4) {
+ if(q > 128 || (q >= 4 && nacl)) {
gconreg(AMOVL, q, D_CX);
gins(AREP, N, N); // repeat
gins(ASTOSL, N, N); // STOL AL,*(DI)+
+ } else if(q >= 4) {
+ p = gins(ADUFFZERO, N, N);
+ p->to.type = D_ADDR;
+ p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
+ // 1 and 128 = magic constants: see ../../pkg/runtime/asm_386.s
+ p->to.offset = 1*(128-q);
} else
while(q > 0) {
gins(ASTOSL, N, N); // STOL AL,*(DI)+
q--;
}
- if(c >= 4) {
- gconreg(AMOVL, c, D_CX);
- gins(AREP, N, N); // repeat
- gins(ASTOSB, N, N); // STOB AL,*(DI)+
- } else
while(c > 0) {
gins(ASTOSB, N, N); // STOB AL,*(DI)+
c--;
@@ -236,7 +287,9 @@ ginscall(Node *f, int proc)
if(proc == 2) {
nodreg(&reg, types[TINT64], D_AX);
gins(ATESTL, &reg, &reg);
- patch(gbranch(AJNE, T, -1), retpc);
+ p = gbranch(AJEQ, T, +1);
+ cgen_ret(N);
+ patch(p, pc);
}
break;
}
@@ -437,15 +490,15 @@ cgen_ret(Node *n)
{
Prog *p;
- genlist(n->list); // copy out args
- if(retpc) {
- gjmp(retpc);
- return;
- }
+ if(n != N)
+ genlist(n->list); // copy out args
+ if(hasdefer)
+ ginscall(deferreturn, 0);
+ genlist(curfn->exit);
p = gins(ARET, N, N);
- if(n->op == ORETJMP) {
+ if(n != N && n->op == ORETJMP) {
p->to.type = D_EXTERN;
- p->to.sym = n->left->sym;
+ p->to.sym = linksym(n->left->sym);
}
}
@@ -663,6 +716,18 @@ dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
gmove(&t2, &n1);
gmove(&t1, ax);
p2 = P;
+ if(nacl) {
+ // Native Client does not relay the divide-by-zero trap
+ // to the executing program, so we must insert a check
+ // for ourselves.
+ nodconst(&n4, t, 0);
+ gins(optoas(OCMP, t), &n1, &n4);
+ p1 = gbranch(optoas(ONE, t), T, +1);
+ if(panicdiv == N)
+ panicdiv = sysfunc("panicdivide");
+ ginscall(panicdiv, -1);
+ patch(p1, pc);
+ }
if(check) {
nodconst(&n4, t, -1);
gins(optoas(OCMP, t), &n1, &n4);
@@ -1246,8 +1311,8 @@ expandchecks(Prog *firstp)
p->link = p1;
p1->lineno = p->lineno;
p2->lineno = p->lineno;
- p1->loc = 9999;
- p2->loc = 9999;
+ p1->pc = 9999;
+ p2->pc = 9999;
p->as = ACMPL;
p->to.type = D_CONST;
p->to.offset = 0;
diff --git a/src/cmd/8g/gobj.c b/src/cmd/8g/gobj.c
index 0517824e0..fa0605e6c 100644
--- a/src/cmd/8g/gobj.c
+++ b/src/cmd/8g/gobj.c
@@ -32,229 +32,6 @@
#include <libc.h>
#include "gg.h"
-void
-zname(Biobuf *b, Sym *s, int t)
-{
- BPUTLE2(b, ANAME); /* as */
- BPUTC(b, t); /* type */
- BPUTC(b, s->sym); /* sym */
-
- Bputname(b, s);
-}
-
-void
-zfile(Biobuf *b, char *p, int n)
-{
- BPUTLE2(b, ANAME);
- BPUTC(b, D_FILE);
- BPUTC(b, 1);
- BPUTC(b, '<');
- Bwrite(b, p, n);
- BPUTC(b, 0);
-}
-
-void
-zhist(Biobuf *b, int line, vlong offset)
-{
- Addr a;
-
- BPUTLE2(b, AHISTORY);
- BPUTLE4(b, line);
- zaddr(b, &zprog.from, 0, 0);
- a = zprog.to;
- if(offset != 0) {
- a.offset = offset;
- a.type = D_CONST;
- }
- zaddr(b, &a, 0, 0);
-}
-
-void
-zaddr(Biobuf *b, Addr *a, int s, int gotype)
-{
- int32 l;
- uint64 e;
- int i, t;
- char *n;
-
- t = 0;
- if(a->index != D_NONE || a->scale != 0)
- t |= T_INDEX;
- if(s != 0)
- t |= T_SYM;
- if(gotype != 0)
- t |= T_GOTYPE;
-
- switch(a->type) {
-
- case D_BRANCH:
- if(a->u.branch == nil)
- fatal("unpatched branch");
- a->offset = a->u.branch->loc;
-
- default:
- t |= T_TYPE;
-
- case D_NONE:
- if(a->offset != 0)
- t |= T_OFFSET;
- if(a->offset2 != 0)
- t |= T_OFFSET2;
- break;
- case D_FCONST:
- t |= T_FCONST;
- break;
- case D_SCONST:
- t |= T_SCONST;
- break;
- }
- BPUTC(b, t);
-
- if(t & T_INDEX) { /* implies index, scale */
- BPUTC(b, a->index);
- BPUTC(b, a->scale);
- }
- if(t & T_OFFSET) { /* implies offset */
- l = a->offset;
- BPUTLE4(b, l);
- }
- if(t & T_OFFSET2) { /* implies offset */
- l = a->offset2;
- BPUTLE4(b, l);
- }
- if(t & T_SYM) /* implies sym */
- BPUTC(b, s);
- if(t & T_FCONST) {
- ieeedtod(&e, a->u.dval);
- BPUTLE4(b, e);
- BPUTLE4(b, e >> 32);
- return;
- }
- if(t & T_SCONST) {
- n = a->u.sval;
- for(i=0; i<NSNAME; i++) {
- BPUTC(b, *n);
- n++;
- }
- return;
- }
- if(t & T_TYPE)
- BPUTC(b, a->type);
- if(t & T_GOTYPE)
- BPUTC(b, gotype);
-}
-
-static struct {
- struct { Sym *sym; short type; } h[NSYM];
- int sym;
-} z;
-
-static void
-zsymreset(void)
-{
- for(z.sym=0; z.sym<NSYM; z.sym++) {
- z.h[z.sym].sym = S;
- z.h[z.sym].type = 0;
- }
- z.sym = 1;
-}
-
-static int
-zsym(Sym *s, int t, int *new)
-{
- int i;
-
- *new = 0;
- if(s == S)
- return 0;
-
- i = s->sym;
- if(i < 0 || i >= NSYM)
- i = 0;
- if(z.h[i].type == t && z.h[i].sym == s)
- return i;
- i = z.sym;
- s->sym = i;
- zname(bout, s, t);
- z.h[i].sym = s;
- z.h[i].type = t;
- if(++z.sym >= NSYM)
- z.sym = 1;
- *new = 1;
- return i;
-}
-
-static int
-zsymaddr(Addr *a, int *new)
-{
- int t;
-
- t = a->type;
- if(t == D_ADDR)
- t = a->index;
- return zsym(a->sym, t, new);
-}
-
-void
-dumpfuncs(void)
-{
- Plist *pl;
- int sf, st, gf, gt, new;
- Sym *s;
- Prog *p;
-
- zsymreset();
-
- // fix up pc
- pcloc = 0;
- for(pl=plist; pl!=nil; pl=pl->link) {
- if(isblank(pl->name))
- continue;
- for(p=pl->firstpc; p!=P; p=p->link) {
- p->loc = pcloc;
- if(p->as != ADATA && p->as != AGLOBL)
- pcloc++;
- }
- }
-
- // put out functions
- for(pl=plist; pl!=nil; pl=pl->link) {
- if(isblank(pl->name))
- continue;
-
- // -S prints code; -SS prints code and data
- if(debug['S'] && (pl->name || debug['S']>1)) {
- s = S;
- if(pl->name != N)
- s = pl->name->sym;
- print("\n--- prog list \"%S\" ---\n", s);
- for(p=pl->firstpc; p!=P; p=p->link)
- print("%P\n", p);
- }
-
- for(p=pl->firstpc; p!=P; p=p->link) {
- for(;;) {
- sf = zsymaddr(&p->from, &new);
- gf = zsym(p->from.gotype, D_EXTERN, &new);
- if(new && sf == gf)
- continue;
- st = zsymaddr(&p->to, &new);
- if(new && (st == sf || st == gf))
- continue;
- gt = zsym(p->to.gotype, D_EXTERN, &new);
- if(new && (gt == sf || gt == gf || gt == st))
- continue;
- break;
- }
-
- BPUTLE2(bout, p->as);
- BPUTLE4(bout, p->lineno);
- zaddr(bout, &p->from, sf, gf);
- zaddr(bout, &p->to, st, gt);
- }
- }
-}
-
int
dsname(Sym *s, int off, char *t, int n)
{
@@ -265,7 +42,7 @@ dsname(Sym *s, int off, char *t, int n)
p->from.index = D_NONE;
p->from.offset = off;
p->from.scale = n;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->to.type = D_SCONST;
p->to.index = D_NONE;
@@ -284,7 +61,7 @@ datastring(char *s, int len, Addr *a)
sym = stringsym(s, len);
a->type = D_EXTERN;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
a->offset = widthptr+4; // skip header
a->etype = TINT32;
@@ -301,7 +78,7 @@ datagostring(Strlit *sval, Addr *a)
sym = stringsym(sval->s, sval->len);
a->type = D_EXTERN;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
a->offset = 0; // header
a->etype = TINT32;
@@ -386,7 +163,7 @@ dstringptr(Sym *s, int off, char *str)
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
@@ -411,7 +188,7 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
datagostring(lit, &p->to);
@@ -439,28 +216,6 @@ dgostringptr(Sym *s, int off, char *str)
return dgostrlitptr(s, off, lit);
}
-
-int
-duintxx(Sym *s, int off, uint64 v, int wid)
-{
- Prog *p;
-
- off = rnd(off, wid);
-
- p = gins(ADATA, N, N);
- p->from.type = D_EXTERN;
- p->from.index = D_NONE;
- p->from.sym = s;
- p->from.offset = off;
- p->from.scale = wid;
- p->to.type = D_CONST;
- p->to.index = D_NONE;
- p->to.offset = v;
- off += wid;
-
- return off;
-}
-
int
dsymptr(Sym *s, int off, Sym *x, int xoff)
{
@@ -471,12 +226,12 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
p = gins(ADATA, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->from.offset = off;
p->from.scale = widthptr;
p->to.type = D_ADDR;
p->to.index = D_EXTERN;
- p->to.sym = x;
+ p->to.sym = linksym(x);
p->to.offset = xoff;
off += widthptr;
diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c
index 34703ba6e..2f3cb28c8 100644
--- a/src/cmd/8g/gsubr.c
+++ b/src/cmd/8g/gsubr.c
@@ -48,7 +48,7 @@ clearp(Prog *p)
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
- p->loc = pcloc;
+ p->pc = pcloc;
pcloc++;
}
@@ -137,7 +137,7 @@ patch(Prog *p, Prog *to)
if(p->to.type != D_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
- p->to.offset = to->loc;
+ p->to.offset = to->pc;
}
Prog*
@@ -161,13 +161,8 @@ newplist(void)
{
Plist *pl;
- pl = mal(sizeof(*pl));
- if(plist == nil)
- plist = pl;
- else
- plast->link = pl;
- plast = pl;
-
+ pl = linknewplist(ctxt);
+
pc = mal(sizeof(*pc));
clearp(pc);
pl->firstpc = pc;
@@ -199,8 +194,8 @@ ggloblnod(Node *nam)
p = gins(AGLOBL, nam, N);
p->lineno = nam->lineno;
- p->from.gotype = ngotype(nam);
- p->to.sym = S;
+ p->from.sym->gotype = linksym(ngotype(nam));
+ p->to.sym = nil;
p->to.type = D_CONST;
p->to.offset = nam->type->width;
if(nam->readonly)
@@ -227,7 +222,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
p = gins(AGLOBL, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
p->to.type = D_CONST;
p->to.index = D_NONE;
p->to.offset = width;
@@ -245,7 +240,7 @@ gtrack(Sym *s)
p = gins(AUSEFIELD, N, N);
p->from.type = D_EXTERN;
p->from.index = D_NONE;
- p->from.sym = s;
+ p->from.sym = linksym(s);
}
int
@@ -273,7 +268,7 @@ afunclit(Addr *a, Node *n)
if(a->type == D_ADDR && a->index == D_EXTERN) {
a->type = D_EXTERN;
a->index = D_NONE;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
}
}
@@ -437,6 +432,7 @@ optoas(int op, Type *t)
case CASE(OADD, TINT32):
case CASE(OADD, TUINT32):
case CASE(OADD, TPTR32):
+ case CASE(OADDPTR, TPTR32):
a = AADDL;
break;
@@ -1048,6 +1044,7 @@ Node*
nodarg(Type *t, int fp)
{
Node *n;
+ NodeList *l;
Type *first;
Iter savet;
@@ -1072,6 +1069,14 @@ nodarg(Type *t, int fp)
break;
case TFIELD:
+ if(fp == 1 && t->sym != S && !isblanksym(t->sym)) {
+ for(l=curfn->dcl; l; l=l->next) {
+ n = l->n;
+ if((n->class == PPARAM || n->class == PPARAMOUT) && n->sym == t->sym)
+ return n;
+ }
+ }
+
n = nod(ONAME, N, N);
n->type = t->type;
n->sym = t->sym;
@@ -1692,7 +1697,6 @@ floatmove(Node *f, Node *t)
gins(ACMPL, &thi, ncon(0));
p1 = gbranch(AJLT, T, 0);
// native
- t1.type = types[TINT64];
nodreg(&r1, types[tt], D_F0);
gins(AFMOVV, &t1, &r1);
if(tt == TFLOAT32)
@@ -2178,10 +2182,12 @@ gins(int as, Node *f, Node *t)
void
naddr(Node *n, Addr *a, int canemitcode)
{
+ Sym *s;
+
a->scale = 0;
a->index = D_NONE;
a->type = D_NONE;
- a->gotype = S;
+ a->gotype = nil;
a->node = N;
if(n == N)
return;
@@ -2193,12 +2199,12 @@ naddr(Node *n, Addr *a, int canemitcode)
case OREGISTER:
a->type = n->val.u.reg;
- a->sym = S;
+ a->sym = nil;
break;
case OINDREG:
a->type = n->val.u.reg+D_INDIR;
- a->sym = n->sym;
+ a->sym = linksym(n->sym);
a->offset = n->xoffset;
break;
@@ -2208,20 +2214,22 @@ naddr(Node *n, Addr *a, int canemitcode)
a->etype = n->left->type->etype;
a->width = n->left->type->width;
a->offset = n->xoffset;
- a->sym = n->left->sym;
+ a->sym = linksym(n->left->sym);
a->type = D_PARAM;
a->node = n->left->orig;
break;
case OCLOSUREVAR:
+ if(!curfn->needctxt)
+ fatal("closurevar without needctxt");
a->type = D_DX+D_INDIR;
a->offset = n->xoffset;
- a->sym = S;
+ a->sym = nil;
break;
case OCFUNC:
naddr(n->left, a, canemitcode);
- a->sym = n->left->sym;
+ a->sym = linksym(n->left->sym);
break;
case ONAME:
@@ -2233,17 +2241,17 @@ naddr(Node *n, Addr *a, int canemitcode)
a->width = n->type->width;
}
a->offset = n->xoffset;
- a->sym = n->sym;
+ s = n->sym;
a->node = n->orig;
//if(a->node >= (Node*)&n)
// fatal("stack node");
- if(a->sym == S)
- a->sym = lookup(".noname");
+ if(s == S)
+ s = lookup(".noname");
if(n->method) {
if(n->type != T)
if(n->type->sym != S)
if(n->type->sym->pkg != nil)
- a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
+ s = pkglookup(s->name, n->type->sym->pkg);
}
switch(n->class) {
@@ -2262,9 +2270,10 @@ naddr(Node *n, Addr *a, int canemitcode)
case PFUNC:
a->index = D_EXTERN;
a->type = D_ADDR;
- a->sym = funcsym(a->sym);
+ s = funcsym(s);
break;
}
+ a->sym = linksym(s);
break;
case OLITERAL:
@@ -2278,7 +2287,7 @@ naddr(Node *n, Addr *a, int canemitcode)
break;
case CTINT:
case CTRUNE:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
@@ -2286,12 +2295,12 @@ naddr(Node *n, Addr *a, int canemitcode)
datagostring(n->val.u.sval, a);
break;
case CTBOOL:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = n->val.u.bval;
break;
case CTNIL:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = 0;
break;
@@ -2327,7 +2336,7 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // ptr(nil)
- a->etype = simtype[TUINTPTR];
+ a->etype = simtype[tptr];
a->offset += Array_array;
a->width = widthptr;
break;
diff --git a/src/cmd/8g/list.c b/src/cmd/8g/list.c
deleted file mode 100644
index ec02ba5c5..000000000
--- a/src/cmd/8g/list.c
+++ /dev/null
@@ -1,316 +0,0 @@
-// Derived from 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 "gg.h"
-
-static int sconsize;
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv); // as
- fmtinstall('P', Pconv); // Prog*
- fmtinstall('D', Dconv); // Addr*
- fmtinstall('R', Rconv); // reg
- fmtinstall('Y', Yconv); // sconst
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
- char scale[40];
-
- p = va_arg(fp->args, Prog*);
- sconsize = 8;
- scale[0] = '\0';
- if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
- snprint(scale, sizeof scale, "%d,", p->from.scale);
- switch(p->as) {
- default:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
-
- case ADATA:
- sconsize = p->from.scale;
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
- p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
- break;
-
- case ATEXT:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Addr *a;
- int i;
- uint32 d1, d2;
-
- a = va_arg(fp->args, Addr*);
- i = a->type;
- if(i >= D_INDIR) {
- if(a->offset)
- snprint(str, sizeof(str), "%d(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof(str), "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- if(a->offset)
- snprint(str, sizeof(str), "$%d,%R", a->offset, i);
- else
- snprint(str, sizeof(str), "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- snprint(str, sizeof(str), "%d", a->u.branch->loc);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
- break;
-
- case D_CONST:
- if(fp->flags & FmtLong) {
- d1 = a->offset;
- d2 = a->offset2;
- snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
- break;
- }
- snprint(str, sizeof(str), "$%d", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof(str), "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
- if(a->gotype)
- fmtprint(fp, "{%s}", a->gotype->name);
- return 0;
-}
-
-static char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
-
- "AH", /* [D_AH] */
- "CH",
- "DH",
- "BH",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "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",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "X0", /* [D_X0] */
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
- snprint(str, sizeof(str), "BAD_R(%d)", r);
- return fmtstrcpy(fp, str);
- }
- return fmtstrcpy(fp, regstr[r]);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-
-int
-Yconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sconsize; 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/cmd/8g/opt.h b/src/cmd/8g/opt.h
index 0d99bdb97..77a69e13a 100644
--- a/src/cmd/8g/opt.h
+++ b/src/cmd/8g/opt.h
@@ -109,6 +109,7 @@ EXTERN Bits externs;
EXTERN Bits params;
EXTERN Bits consts;
EXTERN Bits addrs;
+EXTERN Bits ivar;
EXTERN Bits ovar;
EXTERN int change;
EXTERN int32 maxnr;
@@ -155,8 +156,6 @@ int32 FtoB(int);
int BtoR(int32);
int BtoF(int32);
-#pragma varargck type "D" Adr*
-
/*
* prog.c
*/
diff --git a/src/cmd/8g/peep.c b/src/cmd/8g/peep.c
index 966c0421b..a4e516dd3 100644
--- a/src/cmd/8g/peep.c
+++ b/src/cmd/8g/peep.c
@@ -107,7 +107,7 @@ peep(Prog *firstp)
switch(p->as) {
case ALEAL:
if(regtyp(&p->to))
- if(p->from.sym != S)
+ if(p->from.sym != nil)
if(p->from.index == D_NONE || p->from.index == D_CONST)
conprop(r);
break;
@@ -387,6 +387,8 @@ subprop(Flow *r0)
if(uniqs(r) == nil)
break;
p = r->prog;
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ continue;
proginfo(&info, p);
if(info.flags & Call)
return 0;
@@ -478,7 +480,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
if(debug['P'])
print("; merge; f=%d", f);
}
- t = copyu(p, v2, A);
+ t = copyu(p, v2, nil);
switch(t) {
case 2: /* rar, can't split */
if(debug['P'])
@@ -516,7 +518,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
break;
}
if(!f) {
- t = copyu(p, v1, A);
+ t = copyu(p, v1, nil);
if(!f && (t == 2 || t == 3 || t == 4)) {
f = 1;
if(debug['P'])
@@ -547,7 +549,7 @@ copyu(Prog *p, Adr *v, Adr *s)
switch(p->as) {
case AJMP:
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
@@ -557,7 +559,7 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
case ARET:
- if(s != A)
+ if(s != nil)
return 1;
return 3;
@@ -569,7 +571,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(v->type == p->from.type)
return 2;
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
@@ -584,6 +586,8 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
}
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ return 0;
proginfo(&info, p);
if((info.reguse|info.regset) & RtoB(v->type))
@@ -599,7 +603,7 @@ copyu(Prog *p, Adr *v, Adr *s)
if(info.flags & RightWrite) {
if(copyas(&p->to, v)) {
- if(s != A)
+ if(s != nil)
return copysub(&p->from, v, s, 1);
if(copyau(&p->from, v))
return 4;
@@ -608,7 +612,7 @@ copyu(Prog *p, Adr *v, Adr *s)
}
if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->from, v, s, 1))
return 1;
return copysub(&p->to, v, s, 1);
@@ -727,7 +731,7 @@ loop:
return;
p = r->prog;
- t = copyu(p, v0, A);
+ t = copyu(p, v0, nil);
switch(t) {
case 0: // miss
case 1: // use
@@ -743,7 +747,7 @@ loop:
if(p->from.node == p0->from.node)
if(p->from.offset == p0->from.offset)
if(p->from.scale == p0->from.scale)
- if(p->from.u.vval == p0->from.u.vval)
+ if(p->from.type == D_FCONST && p->from.u.dval == p0->from.u.dval)
if(p->from.index == p0->from.index) {
excise(r);
goto loop;
diff --git a/src/cmd/8g/prog.c b/src/cmd/8g/prog.c
index 14f197b6a..8eed67f6d 100644
--- a/src/cmd/8g/prog.c
+++ b/src/cmd/8g/prog.c
@@ -38,9 +38,11 @@ static ProgInfo progtable[ALAST] = {
[ATEXT]= {Pseudo},
[AFUNCDATA]= {Pseudo},
[APCDATA]= {Pseudo},
- [AUNDEF]= {OK},
+ [AUNDEF]= {Break},
[AUSEFIELD]= {OK},
[ACHECKNIL]= {LeftRead},
+ [AVARDEF]= {Pseudo | RightWrite},
+ [AVARKILL]= {Pseudo | RightWrite},
// NOP is an internal no-op that also stands
// for USED and SET annotations, not the Intel opcode.
@@ -136,11 +138,16 @@ static ProgInfo progtable[ALAST] = {
[AFMOVW]= {SizeW | LeftAddr | RightWrite},
[AFMOVV]= {SizeQ | LeftAddr | RightWrite},
- [AFMOVDP]= {SizeD | LeftRead | RightAddr},
- [AFMOVFP]= {SizeF | LeftRead | RightAddr},
- [AFMOVLP]= {SizeL | LeftRead | RightAddr},
- [AFMOVWP]= {SizeW | LeftRead | RightAddr},
- [AFMOVVP]= {SizeQ | LeftRead | RightAddr},
+ // These instructions are marked as RightAddr
+ // so that the register optimizer does not try to replace the
+ // memory references with integer register references.
+ // But they do not use the previous value at the address, so
+ // we also mark them RightWrite.
+ [AFMOVDP]= {SizeD | LeftRead | RightWrite | RightAddr},
+ [AFMOVFP]= {SizeF | LeftRead | RightWrite | RightAddr},
+ [AFMOVLP]= {SizeL | LeftRead | RightWrite | RightAddr},
+ [AFMOVWP]= {SizeW | LeftRead | RightWrite | RightAddr},
+ [AFMOVVP]= {SizeQ | LeftRead | RightWrite | RightAddr},
[AFMULD]= {SizeD | LeftAddr | RightRdwr},
[AFMULDP]= {SizeD | LeftAddr | RightRdwr},
@@ -193,6 +200,7 @@ static ProgInfo progtable[ALAST] = {
[AMOVSB]= {OK, DI|SI, DI|SI},
[AMOVSL]= {OK, DI|SI, DI|SI},
[AMOVSW]= {OK, DI|SI, DI|SI},
+ [ADUFFCOPY]= {OK, DI|SI, DI|SI|CX},
[AMOVSD]= {SizeD | LeftRead | RightWrite | Move},
[AMOVSS]= {SizeF | LeftRead | RightWrite | Move},
@@ -285,6 +293,7 @@ static ProgInfo progtable[ALAST] = {
[ASTOSB]= {OK, AX|DI, DI},
[ASTOSL]= {OK, AX|DI, DI},
[ASTOSW]= {OK, AX|DI, DI},
+ [ADUFFZERO]= {OK, AX|DI, DI},
[ASUBB]= {SizeB | LeftRead | RightRdwr | SetCarry},
[ASUBL]= {SizeL | LeftRead | RightRdwr | SetCarry},
diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c
index a85c6608a..fd610f87a 100644
--- a/src/cmd/8g/reg.c
+++ b/src/cmd/8g/reg.c
@@ -55,30 +55,6 @@ rcmp(const void *a1, const void *a2)
}
static void
-setoutvar(void)
-{
- Type *t;
- Node *n;
- Addr a;
- Iter save;
- Bits bit;
- int z;
-
- t = structfirst(&save, getoutarg(curfn->type));
- while(t != T) {
- n = nodarg(t, 1);
- a = zprog.from;
- naddr(n, &a, 0);
- bit = mkvar(R, &a);
- for(z=0; z<BITS; z++)
- ovar.b[z] |= bit.b[z];
- t = structnext(&save);
- }
-//if(bany(ovar))
-//print("ovars = %Q\n", ovar);
-}
-
-static void
setaddrs(Bits bit)
{
int i, n;
@@ -108,6 +84,8 @@ static char* regname[] = {
static Node* regnodes[NREGVAR];
+static void walkvardef(Node *n, Reg *r, int active);
+
void
regopt(Prog *firstp)
{
@@ -115,7 +93,7 @@ regopt(Prog *firstp)
Prog *p;
Graph *g;
ProgInfo info;
- int i, z;
+ int i, z, active;
uint32 vreg;
Bits bit;
@@ -124,8 +102,7 @@ regopt(Prog *firstp)
exregoffset = D_DI; // no externals
first = 0;
}
-
- fixjmp(firstp);
+
mergetemp(firstp);
/*
@@ -147,12 +124,10 @@ regopt(Prog *firstp)
params.b[z] = 0;
consts.b[z] = 0;
addrs.b[z] = 0;
+ ivar.b[z] = 0;
ovar.b[z] = 0;
}
- // build list of return variables
- setoutvar();
-
/*
* pass 1
* build aux data structure
@@ -160,12 +135,18 @@ regopt(Prog *firstp)
* find use and set of variables
*/
g = flowstart(firstp, sizeof(Reg));
- if(g == nil)
+ if(g == nil) {
+ for(i=0; i<nvar; i++)
+ var[i].node->opt = nil;
return;
+ }
+
firstr = (Reg*)g->start;
for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog;
+ if(p->as == AVARDEF || p->as == AVARKILL)
+ continue;
proginfo(&info, p);
// Avoid making variables for direct-called functions.
@@ -228,6 +209,26 @@ regopt(Prog *firstp)
dumpit("pass2", &firstr->f, 1);
/*
+ * pass 2.5
+ * iterate propagating fat vardef covering forward
+ * r->act records vars with a VARDEF since the last CALL.
+ * (r->act will be reused in pass 5 for something else,
+ * but we'll be done with it by then.)
+ */
+ active = 0;
+ for(r = firstr; r != R; r = (Reg*)r->f.link) {
+ r->f.active = 0;
+ r->act = zbits;
+ }
+ for(r = firstr; r != R; r = (Reg*)r->f.link) {
+ p = r->f.prog;
+ if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) {
+ active++;
+ walkvardef(p->to.node, r, active);
+ }
+ }
+
+ /*
* pass 3
* iterate propagating usage
* back until flow graph is complete
@@ -367,6 +368,8 @@ brk:
/*
* free aux structures. peep allocates new ones.
*/
+ for(i=0; i<nvar; i++)
+ var[i].node->opt = nil;
flowend(g);
firstr = R;
@@ -423,6 +426,32 @@ brk:
}
}
+static void
+walkvardef(Node *n, Reg *r, int active)
+{
+ Reg *r1, *r2;
+ int bn;
+ Var *v;
+
+ for(r1=r; r1!=R; r1=(Reg*)r1->f.s1) {
+ if(r1->f.active == active)
+ break;
+ r1->f.active = active;
+ if(r1->f.prog->as == AVARKILL && r1->f.prog->to.node == n)
+ break;
+ for(v=n->opt; v!=nil; v=v->nextinnode) {
+ bn = v - var;
+ r1->act.b[bn/32] |= 1L << (bn%32);
+ }
+ if(r1->f.prog->as == ACALL)
+ break;
+ }
+
+ for(r2=r; r2!=r1; r2=(Reg*)r2->f.s1)
+ if(r2->f.s2 != nil)
+ walkvardef(n, (Reg*)r2->f.s2, active);
+}
+
/*
* add mov b,rn
* just after r
@@ -436,7 +465,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1 = mal(sizeof(*p1));
clearp(p1);
- p1->loc = 9999;
+ p1->pc = 9999;
p = r->f.prog;
p1->link = p->link;
@@ -450,7 +479,7 @@ addmove(Reg *r, int bn, int rn, int f)
a->etype = v->etype;
a->type = v->name;
a->node = v->node;
- a->sym = v->node->sym;
+ a->sym = linksym(v->node->sym);
// need to clean this up with wptr and
// some of the defaults
@@ -618,6 +647,16 @@ mkvar(Reg *r, Adr *a)
if(nvar >= NVAR) {
if(debug['w'] > 1 && node != N)
fatal("variable not optimized: %D", a);
+
+ // If we're not tracking a word in a variable, mark the rest as
+ // having its address taken, so that we keep the whole thing
+ // live at all calls. otherwise we might optimize away part of
+ // a variable but not all of it.
+ for(i=0; i<nvar; i++) {
+ v = var+i;
+ if(v->node == node)
+ v->addr = 1;
+ }
goto none;
}
@@ -630,10 +669,13 @@ mkvar(Reg *r, Adr *a)
v->width = w;
v->addr = flag; // funny punning
v->node = node;
-
- if(debug['R'])
- print("bit=%2d et=%2E w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
- ostats.nvar++;
+
+ // node->opt is the head of a linked list
+ // of Vars within the given Node, so that
+ // we can start at a Var and find all the other
+ // Vars in the same Go variable.
+ v->nextinnode = node->opt;
+ node->opt = v;
bit = blsh(i);
if(n == D_EXTERN || n == D_STATIC)
@@ -642,6 +684,46 @@ mkvar(Reg *r, Adr *a)
if(n == D_PARAM)
for(z=0; z<BITS; z++)
params.b[z] |= bit.b[z];
+
+ if(node->class == PPARAM)
+ for(z=0; z<BITS; z++)
+ ivar.b[z] |= bit.b[z];
+ if(node->class == PPARAMOUT)
+ for(z=0; z<BITS; z++)
+ ovar.b[z] |= bit.b[z];
+
+ // Treat values with their address taken as live at calls,
+ // because the garbage collector's liveness analysis in ../gc/plive.c does.
+ // These must be consistent or else we will elide stores and the garbage
+ // collector will see uninitialized data.
+ // The typical case where our own analysis is out of sync is when the
+ // node appears to have its address taken but that code doesn't actually
+ // get generated and therefore doesn't show up as an address being
+ // taken when we analyze the instruction stream.
+ // One instance of this case is when a closure uses the same name as
+ // an outer variable for one of its own variables declared with :=.
+ // The parser flags the outer variable as possibly shared, and therefore
+ // sets addrtaken, even though it ends up not being actually shared.
+ // If we were better about _ elision, _ = &x would suffice too.
+ // The broader := in a closure problem is mentioned in a comment in
+ // closure.c:/^typecheckclosure and dcl.c:/^oldname.
+ if(node->addrtaken)
+ v->addr = 1;
+
+ // Disable registerization for globals, because:
+ // (1) we might panic at any time and we want the recovery code
+ // to see the latest values (issue 1304).
+ // (2) we don't know what pointers might point at them and we want
+ // loads via those pointers to see updated values and vice versa (issue 7995).
+ //
+ // Disable registerization for results if using defer, because the deferred func
+ // might recover and return, causing the current values to be used.
+ if(node->class == PEXTERN || (hasdefer && node->class == PPARAMOUT))
+ v->addr = 1;
+
+ if(debug['R'])
+ print("bit=%2d et=%2E w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
+ ostats.nvar++;
return bit;
@@ -653,7 +735,8 @@ void
prop(Reg *r, Bits ref, Bits cal)
{
Reg *r1, *r2;
- int z;
+ int z, i, j;
+ Var *v, *v1;
for(r1 = r; r1 != R; r1 = (Reg*)r1->f.p1) {
for(z=0; z<BITS; z++) {
@@ -672,10 +755,61 @@ prop(Reg *r, Bits ref, Bits cal)
case ACALL:
if(noreturn(r1->f.prog))
break;
+
+ // Mark all input variables (ivar) as used, because that's what the
+ // liveness bitmaps say. The liveness bitmaps say that so that a
+ // panic will not show stale values in the parameter dump.
+ // Mark variables with a recent VARDEF (r1->act) as used,
+ // so that the optimizer flushes initializations to memory,
+ // so that if a garbage collection happens during this CALL,
+ // the collector will see initialized memory. Again this is to
+ // match what the liveness bitmaps say.
for(z=0; z<BITS; z++) {
- cal.b[z] |= ref.b[z] | externs.b[z];
+ cal.b[z] |= ref.b[z] | externs.b[z] | ivar.b[z] | r1->act.b[z];
ref.b[z] = 0;
}
+
+ // cal.b is the current approximation of what's live across the call.
+ // Every bit in cal.b is a single stack word. For each such word,
+ // find all the other tracked stack words in the same Go variable
+ // (struct/slice/string/interface) and mark them live too.
+ // This is necessary because the liveness analysis for the garbage
+ // collector works at variable granularity, not at word granularity.
+ // It is fundamental for slice/string/interface: the garbage collector
+ // needs the whole value, not just some of the words, in order to
+ // interpret the other bits correctly. Specifically, slice needs a consistent
+ // ptr and cap, string needs a consistent ptr and len, and interface
+ // needs a consistent type word and data word.
+ for(z=0; z<BITS; z++) {
+ if(cal.b[z] == 0)
+ continue;
+ for(i=0; i<32; i++) {
+ if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0)
+ continue;
+ v = var+z*32+i;
+ if(v->node->opt == nil) // v represents fixed register, not Go variable
+ continue;
+
+ // v->node->opt is the head of a linked list of Vars
+ // corresponding to tracked words from the Go variable v->node.
+ // Walk the list and set all the bits.
+ // For a large struct this could end up being quadratic:
+ // after the first setting, the outer loop (for z, i) would see a 1 bit
+ // for all of the remaining words in the struct, and for each such
+ // word would go through and turn on all the bits again.
+ // To avoid the quadratic behavior, we only turn on the bits if
+ // v is the head of the list or if the head's bit is not yet turned on.
+ // This will set the bits at most twice, keeping the overall loop linear.
+ v1 = v->node->opt;
+ j = v1 - var;
+ if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
+ for(; v1 != nil; v1 = v1->nextinnode) {
+ j = v1 - var;
+ cal.b[j/32] |= 1<<(j&31);
+ }
+ }
+ }
+ }
break;
case ATEXT:
@@ -691,17 +825,6 @@ prop(Reg *r, Bits ref, Bits cal)
ref.b[z] = 0;
}
break;
-
- default:
- // Work around for issue 1304:
- // flush modified globals before each instruction.
- for(z=0; z<BITS; z++) {
- cal.b[z] |= externs.b[z];
- // issue 4066: flush modified return variables in case of panic
- if(hasdefer)
- cal.b[z] |= ovar.b[z];
- }
- break;
}
for(z=0; z<BITS; z++) {
ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
@@ -824,18 +947,19 @@ paint1(Reg *r, int bn)
r->act.b[z] |= bb;
p = r->f.prog;
- if(r->use1.b[z] & bb) {
- change += CREF * r->f.loop;
- if(p->as == AFMOVL || p->as == AFMOVW)
- if(BtoR(bb) != D_F0)
- change = -CINF;
- }
-
- if((r->use2.b[z]|r->set.b[z]) & bb) {
- change += CREF * r->f.loop;
- if(p->as == AFMOVL || p->as == AFMOVW)
- if(BtoR(bb) != D_F0)
- change = -CINF;
+ if(r->f.prog->as != ANOP) { // don't give credit for NOPs
+ if(r->use1.b[z] & bb) {
+ change += CREF * r->f.loop;
+ if(p->as == AFMOVL || p->as == AFMOVW)
+ if(BtoR(bb) != D_F0)
+ change = -CINF;
+ }
+ if((r->use2.b[z]|r->set.b[z]) & bb) {
+ change += CREF * r->f.loop;
+ if(p->as == AFMOVL || p->as == AFMOVW)
+ if(BtoR(bb) != D_F0)
+ change = -CINF;
+ }
}
if(STORE(r) & r->regdiff.b[z] & bb) {
@@ -877,7 +1001,7 @@ regset(Reg *r, uint32 bb)
v = zprog.from;
while(b = bb & ~(bb-1)) {
v.type = b & 0xFF ? BtoR(b): BtoF(b);
- c = copyu(r->f.prog, &v, A);
+ c = copyu(r->f.prog, &v, nil);
if(c == 3)
set |= b;
bb &= ~b;
@@ -896,7 +1020,7 @@ reguse(Reg *r, uint32 bb)
v = zprog.from;
while(b = bb & ~(bb-1)) {
v.type = b & 0xFF ? BtoR(b): BtoF(b);
- c = copyu(r->f.prog, &v, A);
+ c = copyu(r->f.prog, &v, nil);
if(c == 1 || c == 2 || c == 4)
set |= b;
bb &= ~b;
@@ -1038,8 +1162,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
void
addreg(Adr *a, int rn)
{
-
- a->sym = 0;
+ a->sym = nil;
a->offset = 0;
a->type = rn;
@@ -1140,15 +1263,15 @@ dumpit(char *str, Flow *r0, int isreg)
r1 = r->p2;
if(r1 != nil) {
print(" pred:");
- for(; r1 != nil; r1 = r->p2link)
- print(" %.4ud", r1->prog->loc);
+ for(; r1 != nil; r1 = r1->p2link)
+ print(" %.4ud", (int)r1->prog->pc);
print("\n");
}
// r1 = r->s1;
// if(r1 != nil) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4ud", r1->prog->loc);
+// print(" %.4ud", (int)r1->prog->pc);
// print("\n");
// }
}
diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h
index 988e50f3e..8e642d390 100644
--- a/src/cmd/8l/8.out.h
+++ b/src/cmd/8l/8.out.h
@@ -547,6 +547,7 @@ enum as
APSUBW,
APUNPCKHQDQ,
APUNPCKLQDQ,
+ APXOR,
ARCPPS,
ARCPSS,
ARSQRTPS,
@@ -578,6 +579,10 @@ enum as
AFUNCDATA,
APCDATA,
ACHECKNIL,
+ AVARDEF,
+ AVARKILL,
+ ADUFFCOPY,
+ ADUFFZERO,
ALAST
};
@@ -631,30 +636,23 @@ enum
D_X5,
D_X6,
D_X7,
-
- D_NONE = 67,
-
- D_BRANCH = 68,
- D_EXTERN = 69,
- D_STATIC = 70,
- D_AUTO = 71,
- D_PARAM = 72,
- D_CONST = 73,
- D_FCONST = 74,
- D_SCONST = 75,
- D_ADDR = 76,
-
- D_FILE,
- D_FILE1,
+
+ D_TLS = 67,
+ D_NONE = 68,
+
+ D_BRANCH = 69,
+ D_EXTERN = 70,
+ D_STATIC = 71,
+ D_AUTO = 72,
+ D_PARAM = 73,
+ D_CONST = 74,
+ D_FCONST = 75,
+ D_SCONST = 76,
+ D_ADDR = 77,
D_INDIR, /* additive */
D_CONST2 = D_INDIR+D_INDIR,
- D_SIZE, /* 8l internal */
- D_PCREL,
- D_GOTOFF,
- D_GOTREL,
- D_TLS,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
@@ -676,15 +674,3 @@ enum
* this is the ranlib header
*/
#define SYMDEF "__.GOSYMDEF"
-
-/*
- * this is the simulated IEEE floating point
- */
-typedef struct ieee Ieee;
-struct ieee
-{
- int32 l; /* contains ls-man 0xffffffff */
- int32 h; /* contains sign 0x80000000
- exp 0x7ff00000
- ms-man 0x000fffff */
-};
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index 3be37ea22..114a3eb5d 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -42,47 +42,20 @@ char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/usr/libexec/ld.elf_so";
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
-
-int32
-entryvalue(void)
-{
- char *a;
- Sym *s;
-
- a = INITENTRY;
- if(*a >= '0' && *a <= '9')
- return atolwhex(a);
- s = lookup(a, 0);
- if(s->type == 0)
- return INITTEXT;
- if(s->type != STEXT)
- diag("entry not text: %s", s->name);
- return s->value;
-}
-
-vlong
-datoff(vlong addr)
-{
- if(addr >= segdata.vaddr)
- return addr - segdata.vaddr + segdata.fileoff;
- if(addr >= segtext.vaddr)
- return addr - segtext.vaddr + segtext.fileoff;
- diag("datoff %#llx", addr);
- return 0;
-}
+char solarisdynld[] = "/lib/ld.so.1";
static int
needlib(char *name)
{
char *p;
- Sym *s;
+ LSym *s;
if(*name == '\0')
return 0;
/* reuse hash code in symbol table */
p = smprint(".dynlib.%s", name);
- s = lookup(p, 0);
+ s = linklookup(ctxt, p, 0);
free(p);
if(s->type == 0) {
s->type = 100; // avoid SDATA, etc.
@@ -93,11 +66,11 @@ needlib(char *name)
int nelfsym = 1;
-static void addpltsym(Sym*);
-static void addgotsym(Sym*);
+static void addpltsym(Link*, LSym*);
+static void addgotsym(Link*, LSym*);
void
-adddynrela(Sym *rela, Sym *s, Reloc *r)
+adddynrela(LSym *rela, LSym *s, Reloc *r)
{
USED(rela);
USED(s);
@@ -106,12 +79,12 @@ adddynrela(Sym *rela, Sym *s, Reloc *r)
}
void
-adddynrel(Sym *s, Reloc *r)
+adddynrel(LSym *s, Reloc *r)
{
- Sym *targ, *rel, *got;
+ LSym *targ, *rel, *got;
targ = r->sym;
- cursym = s;
+ ctxt->cursym = s;
switch(r->type) {
default:
@@ -127,16 +100,16 @@ adddynrel(Sym *s, Reloc *r)
diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ->name);
if(targ->type == 0 || targ->type == SXREF)
diag("unknown symbol %s in pcrel", targ->name);
- r->type = D_PCREL;
+ r->type = R_PCREL;
r->add += 4;
return;
case 256 + R_386_PLT32:
- r->type = D_PCREL;
+ r->type = R_PCREL;
r->add += 4;
if(targ->type == SDYNIMPORT) {
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add += targ->plt;
}
return;
@@ -150,46 +123,46 @@ adddynrel(Sym *s, Reloc *r)
return;
}
s->p[r->off-2] = 0x8d;
- r->type = D_GOTOFF;
+ r->type = R_GOTOFF;
return;
}
- addgotsym(targ);
- r->type = D_CONST; // write r->add during relocsym
+ addgotsym(ctxt, targ);
+ r->type = R_CONST; // write r->add during relocsym
r->sym = S;
r->add += targ->got;
return;
case 256 + R_386_GOTOFF:
- r->type = D_GOTOFF;
+ r->type = R_GOTOFF;
return;
case 256 + R_386_GOTPC:
- r->type = D_PCREL;
- r->sym = lookup(".got", 0);
+ r->type = R_PCREL;
+ r->sym = linklookup(ctxt, ".got", 0);
r->add += 4;
return;
case 256 + R_386_32:
if(targ->type == SDYNIMPORT)
diag("unexpected R_386_32 relocation for dynamic symbol %s", targ->name);
- r->type = D_ADDR;
+ r->type = R_ADDR;
return;
case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 0:
- r->type = D_ADDR;
+ r->type = R_ADDR;
if(targ->type == SDYNIMPORT)
diag("unexpected reloc for dynamic symbol %s", targ->name);
return;
case 512 + MACHO_GENERIC_RELOC_VANILLA*2 + 1:
if(targ->type == SDYNIMPORT) {
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = targ->plt;
- r->type = D_PCREL;
+ r->type = R_PCREL;
return;
}
- r->type = D_PCREL;
+ r->type = R_PCREL;
return;
case 512 + MACHO_FAKE_GOTPCREL:
@@ -201,13 +174,13 @@ adddynrel(Sym *s, Reloc *r)
return;
}
s->p[r->off-2] = 0x8d;
- r->type = D_PCREL;
+ r->type = R_PCREL;
return;
}
- addgotsym(targ);
- r->sym = lookup(".got", 0);
+ addgotsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".got", 0);
r->add += targ->got;
- r->type = D_PCREL;
+ r->type = R_PCREL;
return;
}
@@ -216,21 +189,22 @@ adddynrel(Sym *s, Reloc *r)
return;
switch(r->type) {
- case D_PCREL:
- addpltsym(targ);
- r->sym = lookup(".plt", 0);
+ case R_CALL:
+ case R_PCREL:
+ addpltsym(ctxt, targ);
+ r->sym = linklookup(ctxt, ".plt", 0);
r->add = targ->plt;
return;
- case D_ADDR:
+ case R_ADDR:
if(s->type != SDATA)
break;
if(iself) {
- adddynsym(targ);
- rel = lookup(".rel", 0);
- addaddrplus(rel, s, r->off);
- adduint32(rel, ELF32_R_INFO(targ->dynid, R_386_32));
- r->type = D_CONST; // write r->add during relocsym
+ adddynsym(ctxt, targ);
+ rel = linklookup(ctxt, ".rel", 0);
+ addaddrplus(ctxt, rel, s, r->off);
+ adduint32(ctxt, rel, ELF32_R_INFO(targ->dynid, R_386_32));
+ r->type = R_CONST; // write r->add during relocsym
r->sym = S;
return;
}
@@ -245,22 +219,22 @@ adddynrel(Sym *s, Reloc *r)
// just in case the C code assigns to the variable,
// and of course it only works for single pointers,
// but we only need to support cgo and that's all it needs.
- adddynsym(targ);
- got = lookup(".got", 0);
+ adddynsym(ctxt, targ);
+ got = linklookup(ctxt, ".got", 0);
s->type = got->type | SSUB;
s->outer = got;
s->sub = got->sub;
got->sub = s;
s->value = got->size;
- adduint32(got, 0);
- adduint32(lookup(".linkedit.got", 0), targ->dynid);
+ adduint32(ctxt, got, 0);
+ adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), targ->dynid);
r->type = 256; // ignore during relocsym
return;
}
break;
}
- cursym = s;
+ ctxt->cursym = s;
diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
}
@@ -276,21 +250,23 @@ elfreloc1(Reloc *r, vlong sectoff)
default:
return -1;
- case D_ADDR:
+ case R_ADDR:
if(r->siz == 4)
LPUT(R_386_32 | elfsym<<8);
else
return -1;
break;
- case D_PCREL:
+ case R_CALL:
+ case R_PCREL:
if(r->siz == 4)
LPUT(R_386_PC32 | elfsym<<8);
else
return -1;
break;
- case D_TLS:
+ case R_TLS_LE:
+ case R_TLS_IE:
if(r->siz == 4)
LPUT(R_386_TLS_LE | elfsym<<8);
else
@@ -304,7 +280,7 @@ int
machoreloc1(Reloc *r, vlong sectoff)
{
uint32 v;
- Sym *rs;
+ LSym *rs;
rs = r->xsym;
@@ -326,10 +302,11 @@ machoreloc1(Reloc *r, vlong sectoff)
switch(r->type) {
default:
return -1;
- case D_ADDR:
+ case R_ADDR:
v |= MACHO_GENERIC_RELOC_VANILLA<<28;
break;
- case D_PCREL:
+ case R_CALL:
+ case R_PCREL:
v |= 1<<24; // pc-relative bit
v |= MACHO_GENERIC_RELOC_VANILLA<<28;
break;
@@ -358,17 +335,17 @@ machoreloc1(Reloc *r, vlong sectoff)
}
int
-archreloc(Reloc *r, Sym *s, vlong *val)
+archreloc(Reloc *r, LSym *s, vlong *val)
{
USED(s);
if(linkmode == LinkExternal)
return -1;
switch(r->type) {
- case D_CONST:
+ case R_CONST:
*val = r->add;
return 0;
- case D_GOTOFF:
- *val = symaddr(r->sym) + r->add - symaddr(lookup(".got", 0));
+ case R_GOTOFF:
+ *val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
return 0;
}
return -1;
@@ -377,119 +354,119 @@ archreloc(Reloc *r, Sym *s, vlong *val)
void
elfsetupplt(void)
{
- Sym *plt, *got;
+ LSym *plt, *got;
- plt = lookup(".plt", 0);
- got = lookup(".got.plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
+ got = linklookup(ctxt, ".got.plt", 0);
if(plt->size == 0) {
// pushl got+4
- adduint8(plt, 0xff);
- adduint8(plt, 0x35);
- addaddrplus(plt, got, 4);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x35);
+ addaddrplus(ctxt, plt, got, 4);
// jmp *got+8
- adduint8(plt, 0xff);
- adduint8(plt, 0x25);
- addaddrplus(plt, got, 8);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x25);
+ addaddrplus(ctxt, plt, got, 8);
// zero pad
- adduint32(plt, 0);
+ adduint32(ctxt, plt, 0);
// assume got->size == 0 too
- addaddrplus(got, lookup(".dynamic", 0), 0);
- adduint32(got, 0);
- adduint32(got, 0);
+ addaddrplus(ctxt, got, linklookup(ctxt, ".dynamic", 0), 0);
+ adduint32(ctxt, got, 0);
+ adduint32(ctxt, got, 0);
}
}
static void
-addpltsym(Sym *s)
+addpltsym(Link *ctxt, LSym *s)
{
- Sym *plt, *got, *rel;
+ LSym *plt, *got, *rel;
if(s->plt >= 0)
return;
- adddynsym(s);
+ adddynsym(ctxt, s);
if(iself) {
- plt = lookup(".plt", 0);
- got = lookup(".got.plt", 0);
- rel = lookup(".rel.plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
+ got = linklookup(ctxt, ".got.plt", 0);
+ rel = linklookup(ctxt, ".rel.plt", 0);
if(plt->size == 0)
elfsetupplt();
// jmpq *got+size
- adduint8(plt, 0xff);
- adduint8(plt, 0x25);
- addaddrplus(plt, got, got->size);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x25);
+ addaddrplus(ctxt, plt, got, got->size);
// add to got: pointer to current pos in plt
- addaddrplus(got, plt, plt->size);
+ addaddrplus(ctxt, got, plt, plt->size);
// pushl $x
- adduint8(plt, 0x68);
- adduint32(plt, rel->size);
+ adduint8(ctxt, plt, 0x68);
+ adduint32(ctxt, plt, rel->size);
// jmp .plt
- adduint8(plt, 0xe9);
- adduint32(plt, -(plt->size+4));
+ adduint8(ctxt, plt, 0xe9);
+ adduint32(ctxt, plt, -(plt->size+4));
// rel
- addaddrplus(rel, got, got->size-4);
- adduint32(rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT));
+ addaddrplus(ctxt, rel, got, got->size-4);
+ adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT));
s->plt = plt->size - 16;
} else if(HEADTYPE == Hdarwin) {
// Same laziness as in 6l.
- Sym *plt;
+ LSym *plt;
- plt = lookup(".plt", 0);
+ plt = linklookup(ctxt, ".plt", 0);
- addgotsym(s);
+ addgotsym(ctxt, s);
- adduint32(lookup(".linkedit.plt", 0), s->dynid);
+ adduint32(ctxt, linklookup(ctxt, ".linkedit.plt", 0), s->dynid);
// jmpq *got+size(IP)
s->plt = plt->size;
- adduint8(plt, 0xff);
- adduint8(plt, 0x25);
- addaddrplus(plt, lookup(".got", 0), s->got);
+ adduint8(ctxt, plt, 0xff);
+ adduint8(ctxt, plt, 0x25);
+ addaddrplus(ctxt, plt, linklookup(ctxt, ".got", 0), s->got);
} else {
diag("addpltsym: unsupported binary format");
}
}
static void
-addgotsym(Sym *s)
+addgotsym(Link *ctxt, LSym *s)
{
- Sym *got, *rel;
+ LSym *got, *rel;
if(s->got >= 0)
return;
- adddynsym(s);
- got = lookup(".got", 0);
+ adddynsym(ctxt, s);
+ got = linklookup(ctxt, ".got", 0);
s->got = got->size;
- adduint32(got, 0);
+ adduint32(ctxt, got, 0);
if(iself) {
- rel = lookup(".rel", 0);
- addaddrplus(rel, got, s->got);
- adduint32(rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT));
+ rel = linklookup(ctxt, ".rel", 0);
+ addaddrplus(ctxt, rel, got, s->got);
+ adduint32(ctxt, rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT));
} else if(HEADTYPE == Hdarwin) {
- adduint32(lookup(".linkedit.got", 0), s->dynid);
+ adduint32(ctxt, linklookup(ctxt, ".linkedit.got", 0), s->dynid);
} else {
diag("addgotsym: unsupported binary format");
}
}
void
-adddynsym(Sym *s)
+adddynsym(Link *ctxt, LSym *s)
{
- Sym *d;
+ LSym *d;
int t;
char *name;
@@ -499,20 +476,20 @@ adddynsym(Sym *s)
if(iself) {
s->dynid = nelfsym++;
- d = lookup(".dynsym", 0);
+ d = linklookup(ctxt, ".dynsym", 0);
/* name */
name = s->extname;
- adduint32(d, addstring(lookup(".dynstr", 0), name));
+ adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
/* value */
if(s->type == SDYNIMPORT)
- adduint32(d, 0);
+ adduint32(ctxt, d, 0);
else
- addaddr(d, s);
+ addaddr(ctxt, d, s);
/* size */
- adduint32(d, 0);
+ adduint32(ctxt, d, 0);
/* type */
t = STB_GLOBAL << 4;
@@ -520,12 +497,12 @@ adddynsym(Sym *s)
t |= STT_FUNC;
else
t |= STT_OBJECT;
- adduint8(d, t);
- adduint8(d, 0);
+ adduint8(ctxt, d, t);
+ adduint8(ctxt, d, 0);
/* shndx */
if(s->type == SDYNIMPORT)
- adduint16(d, SHN_UNDEF);
+ adduint16(ctxt, d, SHN_UNDEF);
else {
switch(s->type) {
default:
@@ -542,7 +519,7 @@ adddynsym(Sym *s)
t = 14;
break;
}
- adduint16(d, t);
+ adduint16(ctxt, d, t);
}
} else if(HEADTYPE == Hdarwin) {
diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
@@ -556,16 +533,16 @@ adddynsym(Sym *s)
void
adddynlib(char *lib)
{
- Sym *s;
+ LSym *s;
if(!needlib(lib))
return;
if(iself) {
- s = lookup(".dynstr", 0);
+ s = linklookup(ctxt, ".dynstr", 0);
if(s->size == 0)
addstring(s, "");
- elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib));
+ elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
} else if(HEADTYPE == Hdarwin) {
machoadddynlib(lib);
} else if(HEADTYPE != Hwindows) {
@@ -576,10 +553,10 @@ adddynlib(char *lib)
void
asmb(void)
{
- int32 v, magic;
+ int32 magic;
uint32 symo, dwarfoff, machlink;
Section *sect;
- Sym *sym;
+ LSym *sym;
int i;
if(debug['v'])
@@ -641,18 +618,7 @@ asmb(void)
default:
if(iself)
goto Elfsym;
- case Hgarbunix:
- symo = rnd(HEADR+segtext.filelen, 8192)+segdata.filelen;
- break;
- case Hunixcoff:
- symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
- break;
- case Hplan9x32:
- symo = HEADR+segtext.filelen+segdata.filelen;
- break;
- case Hmsdoscom:
- case Hmsdosexe:
- debug['s'] = 1;
+ case Hplan9:
symo = HEADR+segtext.filelen+segdata.filelen;
break;
case Hdarwin:
@@ -685,11 +651,11 @@ asmb(void)
elfemitreloc();
}
break;
- case Hplan9x32:
+ case Hplan9:
asmplan9sym();
cflush();
- sym = lookup("pclntab", 0);
+ sym = linklookup(ctxt, "pclntab", 0);
if(sym != nil) {
lcsize = sym->np;
for(i=0; i < lcsize; i++)
@@ -715,96 +681,7 @@ asmb(void)
cseek(0L);
switch(HEADTYPE) {
default:
- case Hgarbunix: /* garbage */
- lputb(0x160L<<16); /* magic and sections */
- lputb(0L); /* time and date */
- lputb(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen);
- lputb(symsize); /* nsyms */
- lputb((0x38L<<16)|7L); /* size of optional hdr and flags */
- lputb((0413<<16)|0437L); /* magic and version */
- lputb(rnd(HEADR+segtext.filelen, 4096)); /* sizes */
- lputb(segdata.filelen);
- lputb(segdata.len - segdata.filelen);
- lputb(entryvalue()); /* va of entry */
- lputb(INITTEXT-HEADR); /* va of base of text */
- lputb(segdata.vaddr); /* va of base of data */
- lputb(segdata.vaddr+segdata.filelen); /* va of base of bss */
- lputb(~0L); /* gp reg mask */
- lputb(0L);
- lputb(0L);
- lputb(0L);
- lputb(0L);
- lputb(~0L); /* gp value ?? */
- break;
- case Hunixcoff: /* unix coff */
- /*
- * file header
- */
- lputl(0x0004014c); /* 4 sections, magic */
- lputl(0); /* unix time stamp */
- lputl(0); /* symbol table */
- lputl(0); /* nsyms */
- lputl(0x0003001c); /* flags, sizeof a.out header */
- /*
- * a.out header
- */
- lputl(0x10b); /* magic, version stamp */
- lputl(rnd(segtext.filelen, INITRND)); /* text sizes */
- lputl(segdata.filelen); /* data sizes */
- lputl(segdata.len - segdata.filelen); /* bss sizes */
- lputb(entryvalue()); /* va of entry */
- lputl(INITTEXT); /* text start */
- lputl(segdata.vaddr); /* data start */
- /*
- * text section header
- */
- s8put(".text");
- lputl(HEADR); /* pa */
- lputl(HEADR); /* va */
- lputl(segtext.filelen); /* text size */
- lputl(HEADR); /* file offset */
- lputl(0); /* relocation */
- lputl(0); /* line numbers */
- lputl(0); /* relocation, line numbers */
- lputl(0x20); /* flags text only */
- /*
- * data section header
- */
- s8put(".data");
- lputl(segdata.vaddr); /* pa */
- lputl(segdata.vaddr); /* va */
- lputl(segdata.filelen); /* data size */
- lputl(HEADR+segtext.filelen); /* file offset */
- lputl(0); /* relocation */
- lputl(0); /* line numbers */
- lputl(0); /* relocation, line numbers */
- lputl(0x40); /* flags data only */
- /*
- * bss section header
- */
- s8put(".bss");
- lputl(segdata.vaddr+segdata.filelen); /* pa */
- lputl(segdata.vaddr+segdata.filelen); /* va */
- lputl(segdata.len - segdata.filelen); /* bss size */
- lputl(0); /* file offset */
- lputl(0); /* relocation */
- lputl(0); /* line numbers */
- lputl(0); /* relocation, line numbers */
- lputl(0x80); /* flags bss only */
- /*
- * comment section header
- */
- s8put(".comment");
- lputl(0); /* pa */
- lputl(0); /* va */
- lputl(symsize+lcsize); /* comment size */
- lputl(HEADR+segtext.filelen+segdata.filelen); /* file offset */
- lputl(HEADR+segtext.filelen+segdata.filelen); /* offset of syms */
- lputl(HEADR+segtext.filelen+segdata.filelen+symsize);/* offset of line numbers */
- lputl(0); /* relocation, line numbers */
- lputl(0x200); /* flags comment only */
- break;
- case Hplan9x32: /* plan9 */
+ case Hplan9: /* plan9 */
magic = 4*11*11+7;
lputb(magic); /* magic */
lputb(segtext.filelen); /* sizes */
@@ -815,31 +692,6 @@ asmb(void)
lputb(spsize); /* sp offsets */
lputb(lcsize); /* line offsets */
break;
- case Hmsdoscom:
- /* MS-DOS .COM */
- break;
- case Hmsdosexe:
- /* fake MS-DOS .EXE */
- v = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
- wputl(0x5A4D); /* 'MZ' */
- wputl(v % 512); /* bytes in last page */
- wputl(rnd(v, 512)/512); /* total number of pages */
- wputl(0x0000); /* number of reloc items */
- v = rnd(HEADR-(INITTEXT & 0xFFFF), 16);
- wputl(v/16); /* size of header */
- wputl(0x0000); /* minimum allocation */
- wputl(0xFFFF); /* maximum allocation */
- wputl(0x0000); /* initial ss value */
- wputl(0x0100); /* initial sp value */
- wputl(0x0000); /* complemented checksum */
- v = entryvalue();
- wputl(v); /* initial ip value (!) */
- wputl(0x0000); /* initial cs value */
- wputl(0x0000);
- wputl(0x0000);
- wputl(0x003E); /* reloc table offset */
- wputl(0x0000); /* overlay number */
- break;
case Hdarwin:
asmbmacho();
break;
@@ -848,6 +700,7 @@ asmb(void)
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hnacl:
asmbelf(symo);
break;
case Hwindows:
diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h
index 814aa1458..c9695ade0 100644
--- a/src/cmd/8l/l.h
+++ b/src/cmd/8l/l.h
@@ -31,6 +31,7 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
+#include <link.h>
#include "8.out.h"
#ifndef EXTERN
@@ -42,141 +43,14 @@ enum
thechar = '8',
PtrSize = 4,
IntSize = 4,
+ RegSize = 4,
MaxAlign = 32, // max data alignment
FuncAlign = 16
};
#define P ((Prog*)0)
-#define S ((Sym*)0)
-#define TNAME (cursym?cursym->name:noname)
-
-typedef struct Adr Adr;
-typedef struct Prog Prog;
-typedef struct Sym Sym;
-typedef struct Auto Auto;
-typedef struct Optab Optab;
-typedef struct Reloc Reloc;
-
-struct Adr
-{
- union
- {
- int32 u0offset;
- char u0scon[8];
- Prog *u0cond; /* not used, but should be D_BRANCH */
- Ieee u0ieee;
- char *u0sbig;
- } u0;
- Sym* sym;
- short type;
- uchar index;
- char scale;
- int32 offset2;
-};
-
-#define offset u0.u0offset
-#define scon u0.u0scon
-#define cond u0.u0cond
-#define ieee u0.u0ieee
-#define sbig u0.u0sbig
-
-struct Reloc
-{
- int32 off;
- uchar siz;
- uchar done;
- int32 type;
- int32 add;
- int32 xadd;
- Sym* sym;
- Sym* xsym;
-};
-
-struct Prog
-{
- Adr from;
- Adr to;
- Prog* forwd;
- Prog* comefrom;
- Prog* link;
- Prog* pcond; /* work on this */
- int32 pc;
- int32 spadj;
- int32 line;
- short as;
- char width; /* fake for DATA */
- char ft; /* oclass cache */
- char tt;
- uchar mark; /* work on these */
- uchar back;
- uchar bigjmp;
-};
-#define datasize from.scale
-#define textflag from.scale
-#define iscall(p) ((p)->as == ACALL)
-
-struct Auto
-{
- Sym* asym;
- Auto* link;
- int32 aoffset;
- short type;
- Sym* gotype;
-};
-struct Sym
-{
- char* name;
- char* extname; // name used in external object files
- short type;
- short version;
- uchar dupok;
- uchar reachable;
- uchar cgoexport;
- uchar special;
- uchar stkcheck;
- uchar hide;
- int32 value;
- int32 size;
- int32 sig;
- int32 dynid;
- int32 plt;
- int32 got;
- int32 align; // if non-zero, required alignment in bytes
- int32 elfsym;
- int32 args; // size of stack frame incoming arguments area
- Sym* hash; // in hash table
- Sym* allsym; // in all symbol list
- Sym* next; // in text or data list
- Sym* sub; // in sub list
- Sym* outer; // container of sub
- Sym* gotype;
- Sym* reachparent;
- Sym* queue;
- char* file;
- char* dynimplib;
- char* dynimpvers;
- struct Section* sect;
- struct Hist* hist; // for ATEXT
-
- // STEXT
- Auto* autom;
- Prog* text;
-
- // SDATA, SBSS
- uchar* p;
- int32 np;
- int32 maxp;
- Reloc* r;
- int32 nr;
- int32 maxr;
-};
-struct Optab
-{
- short as;
- uchar* ytab;
- uchar prefix;
- uchar op[13];
-};
+#define S ((LSym*)0)
+#define TNAME (ctxt->cursym?ctxt->cursym->name:noname)
enum
{
@@ -185,202 +59,36 @@ enum
MINLC = 1,
MAXIO = 8192,
MAXHIST = 40, /* limit of path elements for history symbols */
-
- Yxxx = 0,
- Ynone,
- Yi0,
- Yi1,
- Yi8,
- Yi32,
- 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,
- 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,
- 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 */
};
-#pragma varargck type "A" int
-#pragma varargck type "D" Adr*
#pragma varargck type "I" uchar*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-#pragma varargck type "Y" Sym*
-#pragma varargck type "Z" char*
-#pragma varargck type "i" char*
-EXTERN int32 HEADR;
-EXTERN int32 HEADTYPE;
-EXTERN int32 INITRND;
-EXTERN int32 INITTEXT;
-EXTERN int32 INITDAT;
-EXTERN char* INITENTRY; /* entry point */
-EXTERN char* pcstr;
-EXTERN Auto* curauto;
-EXTERN Auto* curhist;
-EXTERN Prog* curp;
-EXTERN Sym* cursym;
-EXTERN Sym* datap;
+EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN char literal[32];
-EXTERN Sym* etextp;
EXTERN Prog* firstp;
-EXTERN uchar ycover[Ymax*Ymax];
-EXTERN uchar* andptr;
-EXTERN uchar and[100];
-EXTERN char reg[D_NONE];
EXTERN int32 lcsize;
-EXTERN int maxop;
-EXTERN int nerrors;
-EXTERN char* noname;
-EXTERN int32 pc;
EXTERN char* rpath;
EXTERN int32 spsize;
-EXTERN Sym* symlist;
+EXTERN LSym* symlist;
EXTERN int32 symsize;
-EXTERN Sym* textp;
EXTERN int32 textsize;
-EXTERN Prog zprg;
-EXTERN int dtype;
-EXTERN int tlsoffset;
-EXTERN Sym* adrgotype; // type symbol on last Adr read
-EXTERN Sym* fromgotype; // type symbol on last p->from read
-extern Optab optab[];
-extern char* anames[];
-
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Iconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Sconv(Fmt*);
-void addhist(int32, int);
-Prog* appendp(Prog*);
+int Iconv(Fmt *fp);
+void adddynlib(char *lib);
+void adddynrel(LSym *s, Reloc *r);
+void adddynrela(LSym *rela, LSym *s, Reloc *r);
+void adddynsym(Link *ctxt, LSym *s);
+int archreloc(Reloc *r, LSym *s, vlong *val);
void asmb(void);
-void asmdyn(void);
-void asmins(Prog*);
-void asmsym(void);
-int32 atolwhex(char*);
-Prog* brchain(Prog*);
-Prog* brloop(Prog*);
-void cflush(void);
-Prog* copyp(Prog*);
-vlong cpos(void);
-double cputime(void);
-void diag(char*, ...);
-void dodata(void);
-void doelf(void);
-void doprof1(void);
-void doprof2(void);
-void dostkoff(void);
-int32 entryvalue(void);
-void follow(void);
-void instinit(void);
+int elfreloc1(Reloc *r, vlong sectoff);
+void elfsetupplt(void);
void listinit(void);
-Sym* lookup(char*, int);
-void lputb(int32);
-void lputl(int32);
-void vputl(uint64);
-void strnput(char*, int);
-void main(int, char*[]);
-void* mal(uint32);
-int opsize(Prog*);
-void patch(void);
-Prog* prg(void);
-int relinv(int);
-int32 rnd(int32, int32);
-void s8put(char*);
-void span(void);
-void undef(void);
-int32 symaddr(Sym*);
-void wput(ushort);
-void wputl(ushort);
-void xdefine(char*, int, int32);
-
-uint32 machheadr(void);
-vlong addaddr(Sym *s, Sym *t);
-vlong addsize(Sym *s, Sym *t);
-vlong addstring(Sym *s, char *str);
-vlong adduint16(Sym *s, uint16 v);
-vlong adduint32(Sym *s, uint32 v);
-vlong adduint64(Sym *s, uint64 v);
-vlong adduint8(Sym *s, uint8 v);
-vlong adduintxx(Sym *s, uint64 v, int wid);
-
-/*
- * go.c
- */
-void deadcode(void);
+int machoreloc1(Reloc *r, vlong sectoff);
+void main(int argc, char *argv[]);
+int32 rnd(int32 v, int32 r);
+void s8put(char *n);
+char* xsymname(LSym *s);
/* Native is little-endian */
#define LPUT(a) lputl(a)
diff --git a/src/cmd/8l/list.c b/src/cmd/8l/list.c
index e2a2ec5ed..0a7534060 100644
--- a/src/cmd/8l/list.c
+++ b/src/cmd/8l/list.c
@@ -36,297 +36,10 @@
void
listinit(void)
{
-
- fmtinstall('R', Rconv);
- fmtinstall('A', Aconv);
- fmtinstall('D', Dconv);
- fmtinstall('S', Sconv);
- fmtinstall('P', Pconv);
+ listinit8();
fmtinstall('I', Iconv);
}
-static Prog *bigP;
-
-int
-Pconv(Fmt *fp)
-{
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- bigP = p;
- switch(p->as) {
- case ATEXT:
- if(p->from.scale) {
- fmtprint(fp, "(%d) %A %D,%d,%D",
- p->line, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- default:
- fmtprint(fp, "(%d) %A %D,%D",
- p->line, p->as, &p->from, &p->to);
- break;
- case ADATA:
- case AINIT_:
- case ADYNT_:
- fmtprint(fp, "(%d) %A %D/%d,%D",
- p->line, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- bigP = P;
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
-}
-
-char*
-xsymname(Sym *s)
-{
- if(s == nil)
- return "!!noname!!";
- return s->name;
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Adr *a;
- int i;
-
- a = va_arg(fp->args, Adr*);
- i = a->type;
- if(i >= D_INDIR && i < 2*D_INDIR) {
- if(a->offset)
- snprint(str, sizeof str, "%d(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof str, "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- snprint(str, sizeof str, "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(bigP != P && bigP->pcond != P)
- if(a->sym != S)
- snprint(str, sizeof str, "%ux+%s", bigP->pcond->pc,
- a->sym->name);
- else
- snprint(str, sizeof str, "%ux", bigP->pcond->pc);
- else
- snprint(str, sizeof str, "%d(PC)", a->offset);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof str, "%s+%d(SB)", xsymname(a->sym), a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof str, "%s<%d>+%d(SB)", xsymname(a->sym),
- a->sym->version, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof str, "%s+%d(SP)", xsymname(a->sym), a->offset);
- break;
-
- case D_PARAM:
- if(a->sym)
- snprint(str, sizeof str, "%s+%d(FP)", a->sym->name, a->offset);
- else
- snprint(str, sizeof str, "%d(FP)", a->offset);
- break;
-
- case D_CONST:
- snprint(str, sizeof str, "$%d", a->offset);
- break;
-
- case D_CONST2:
- snprint(str, sizeof str, "$%d-%d", a->offset, a->offset2);
- break;
-
- case D_FCONST:
- snprint(str, sizeof str, "$(%.8ux,%.8ux)", a->ieee.h, a->ieee.l);
- break;
-
- case D_SCONST:
- snprint(str, sizeof str, "$\"%S\"", a->scon);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof str, "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- sprint(s, "(%R*%d)", (int)a->index, a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
-// if(a->gotype)
-// fmtprint(fp, "«%s»", a->gotype->name);
- return 0;
-}
-
-char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
- "AH",
- "CH",
- "DH",
- "BH",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "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",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "X0",
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_AL && r <= D_NONE)
- sprint(str, "%s", regstr[r-D_AL]);
- else
- sprint(str, "gok(%d)", r);
-
- return fmtstrcpy(fp, str);
-}
-
-int
-Sconv(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);
-}
-
int
Iconv(Fmt *fp)
{
@@ -352,27 +65,3 @@ Iconv(Fmt *fp)
free(s);
return 0;
}
-
-void
-diag(char *fmt, ...)
-{
- char buf[1024], *tn, *sep;
- va_list arg;
-
- tn = "";
- sep = "";
- if(cursym != S) {
- tn = cursym->name;
- sep = ": ";
- }
- va_start(arg, fmt);
- vseprint(buf, buf+sizeof(buf), fmt, arg);
- va_end(arg);
- print("%s%s%s\n", tn, sep, buf);
-
- nerrors++;
- if(nerrors > 20) {
- print("too many errors\n");
- errorexit();
- }
-}
diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c
index 3fdc41381..1b65c5eb9 100644
--- a/src/cmd/8l/obj.c
+++ b/src/cmd/8l/obj.c
@@ -30,7 +30,6 @@
// Reading object files.
-#define EXTERN
#include "l.h"
#include "../ld/lib.h"
#include "../ld/elf.h"
@@ -39,110 +38,17 @@
#include "../ld/pe.h"
#include <ar.h>
-#ifndef DEFAULT
-#define DEFAULT '9'
-#endif
-
-char *noname = "<none>";
-char *thestring = "386";
-
-Header headers[] = {
- "garbunix", Hgarbunix,
- "unixcoff", Hunixcoff,
- "plan9", Hplan9x32,
- "msdoscom", Hmsdoscom,
- "msdosexe", Hmsdosexe,
- "darwin", Hdarwin,
- "dragonfly", Hdragonfly,
- "linux", Hlinux,
- "freebsd", Hfreebsd,
- "netbsd", Hnetbsd,
- "openbsd", Hopenbsd,
- "windows", Hwindows,
- "windowsgui", Hwindows,
- 0, 0
-};
-
-/*
- * -Hgarbunix -T0x40004C -D0x10000000 is garbage unix
- * -Hunixcoff -T0xd0 -R4 is unix coff
- * -Hplan9 -T4128 -R4096 is plan9 format
- * -Hmsdoscom -Tx -Rx is MS-DOS .COM
- * -Hmsdosexe -Tx -Rx is fake MS-DOS .EXE
- * -Hdarwin -Tx -Rx is Apple Mach-O
- * -Hdragonfly -Tx -Rx is DragonFly ELF32
- * -Hlinux -Tx -Rx is Linux ELF32
- * -Hfreebsd -Tx -Rx is FreeBSD ELF32
- * -Hnetbsd -Tx -Rx is NetBSD ELF32
- * -Hopenbsd -Tx -Rx is OpenBSD ELF32
- * -Hwindows -Tx -Rx is MS Windows PE32
- */
+char* thestring = "386";
+LinkArch* thelinkarch = &link386;
void
-main(int argc, char *argv[])
+linkarchinit(void)
{
- Binit(&bso, 1, OWRITE);
- listinit();
- memset(debug, 0, sizeof(debug));
- nerrors = 0;
- outfile = nil;
- HEADTYPE = -1;
- INITTEXT = -1;
- INITDAT = -1;
- INITRND = -1;
- INITENTRY = 0;
- linkmode = LinkAuto;
- nuxiinit();
-
- flagcount("1", "use alternate profiling code", &debug['1']);
- flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
- flagstr("E", "sym: entry symbol", &INITENTRY);
- flagint32("D", "addr: data address", &INITDAT);
- flagfn1("I", "interp: set ELF interp", setinterp);
- flagfn1("L", "dir: add dir to library path", Lflag);
- flagfn1("H", "head: header type", setheadtype);
- flagcount("K", "add stack underflow checks", &debug['K']);
- flagcount("O", "print pc-line tables", &debug['O']);
- flagcount("Q", "debug byte-register code gen", &debug['Q']);
- flagint32("R", "rnd: address rounding", &INITRND);
- flagcount("S", "check type signatures", &debug['S']);
- flagint32("T", "addr: text address", &INITTEXT);
- flagfn0("V", "print version and exit", doversion);
- flagcount("W", "disassemble input", &debug['W']);
- flagfn2("X", "name value: define string data", addstrdata);
- flagcount("Z", "clear stack frame on entry", &debug['Z']);
- flagcount("a", "disassemble output", &debug['a']);
- flagcount("c", "dump call graph", &debug['c']);
- flagcount("d", "disable dynamic executable", &debug['d']);
- flagstr("extld", "linker to run in external mode", &extld);
- flagstr("extldflags", "flags for external linker", &extldflags);
- flagcount("f", "ignore version mismatch", &debug['f']);
- flagcount("g", "disable go package data checks", &debug['g']);
- flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
- flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
- flagstr("k", "sym: set field tracking symbol", &tracksym);
- flagstr("o", "outfile: set output file", &outfile);
- flagcount("p", "insert profiling code", &debug['p']);
- flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
- flagcount("race", "enable race detector", &flag_race);
- flagcount("s", "disable symbol table", &debug['s']);
- flagcount("n", "dump symbol table", &debug['n']);
- flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
- flagcount("u", "reject unsafe packages", &debug['u']);
- flagcount("v", "print link trace", &debug['v']);
- flagcount("w", "disable DWARF generation", &debug['w']);
- // TODO: link mode flag
-
- flagparse(&argc, &argv, usage);
-
- if(argc != 1)
- usage();
-
- mywhatsys(); // get goos
-
- if(HEADTYPE == -1)
- HEADTYPE = headtype(goos);
+}
+void
+archinit(void)
+{
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash.
if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
@@ -164,40 +70,12 @@ main(int argc, char *argv[])
break;
}
- if(outfile == nil) {
- if(HEADTYPE == Hwindows)
- outfile = "8.out.exe";
- else
- outfile = "8.out";
- }
-
- libinit();
-
switch(HEADTYPE) {
default:
diag("unknown -H option");
errorexit();
- case Hgarbunix: /* this is garbage */
- HEADR = 20L+56L;
- if(INITTEXT == -1)
- INITTEXT = 0x40004CL;
- if(INITDAT == -1)
- INITDAT = 0x10000000L;
- if(INITRND == -1)
- INITRND = 0;
- break;
- case Hunixcoff: /* is unix coff */
- HEADR = 0xd0L;
- if(INITTEXT == -1)
- INITTEXT = 0xd0;
- if(INITDAT == -1)
- INITDAT = 0x400000;
- if(INITRND == -1)
- INITRND = 0;
- break;
- case Hplan9x32: /* plan 9 */
- tlsoffset = -8;
+ case Hplan9: /* plan 9 */
HEADR = 32L;
if(INITTEXT == -1)
INITTEXT = 4096+32;
@@ -206,33 +84,7 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
- case Hmsdoscom: /* MS-DOS .COM */
- HEADR = 0;
- if(INITTEXT == -1)
- INITTEXT = 0x0100;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 4;
- break;
- case Hmsdosexe: /* fake MS-DOS .EXE */
- HEADR = 0x200;
- if(INITTEXT == -1)
- INITTEXT = 0x0100;
- if(INITDAT == -1)
- INITDAT = 0;
- if(INITRND == -1)
- INITRND = 4;
- HEADR += (INITTEXT & 0xFFFF);
- if(debug['v'])
- Bprint(&bso, "HEADR = 0x%d\n", HEADR);
- break;
case Hdarwin: /* apple MACH */
- /*
- * OS X system constant - offset from %gs to our TLS.
- * Explained in ../../pkg/runtime/cgo/gcc_darwin_386.c.
- */
- tlsoffset = 0x468;
machoinit();
HEADR = INITIAL_MACHO_HEADR;
if(INITTEXT == -1)
@@ -247,13 +99,6 @@ main(int argc, char *argv[])
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
- /*
- * ELF uses TLS offsets negative from %gs.
- * Translate 0(GS) and 4(GS) into -8(GS) and -4(GS).
- * Also known to ../../pkg/runtime/sys_linux_386.s
- * and ../../pkg/runtime/cgo/gcc_linux_386.c.
- */
- tlsoffset = -8;
elfinit();
HEADR = ELFRESERVE;
if(INITTEXT == -1)
@@ -263,6 +108,19 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
+
+ case Hnacl:
+ elfinit();
+ HEADR = 0x10000;
+ funcalign = 32;
+ if(INITTEXT == -1)
+ INITTEXT = 0x20000;
+ if(INITDAT == -1)
+ INITDAT = 0;
+ if(INITRND == -1)
+ INITRND = 0x10000;
+ break;
+
case Hwindows: /* PE executable */
peinit();
HEADR = PEFILEHEADR;
@@ -275,518 +133,6 @@ main(int argc, char *argv[])
break;
}
if(INITDAT != 0 && INITRND != 0)
- print("warning: -D0x%ux is ignored because of -R0x%ux\n",
+ print("warning: -D0x%llux is ignored because of -R0x%ux\n",
INITDAT, INITRND);
- if(debug['v'])
- Bprint(&bso, "HEADER = -H0x%d -T0x%ux -D0x%ux -R0x%ux\n",
- HEADTYPE, INITTEXT, INITDAT, INITRND);
- Bflush(&bso);
-
- instinit();
- zprg.link = P;
- zprg.pcond = P;
- zprg.back = 2;
- zprg.as = AGOK;
- zprg.from.type = D_NONE;
- zprg.from.index = D_NONE;
- zprg.from.scale = 1;
- zprg.to = zprg.from;
-
- pcstr = "%.6ux ";
- histgen = 0;
- pc = 0;
- dtype = 4;
- version = 0;
- cbp = buf.cbuf;
- cbc = sizeof(buf.cbuf);
-
- addlibpath("command line", "command line", argv[0], "main");
- loadlib();
- deadcode();
- patch();
- follow();
- doelf();
- if(HEADTYPE == Hdarwin)
- domacho();
- if(HEADTYPE == Hwindows)
- dope();
- dostkoff();
- dostkcheck();
- if(debug['p'])
- if(debug['1'])
- doprof1();
- else
- doprof2();
- span();
- addexport();
- textaddress();
- pclntab();
- symtab();
- dodata();
- address();
- doweak();
- reloc();
- asmb();
- undef();
- hostlink();
-
- if(debug['v']) {
- Bprint(&bso, "%5.2f cpu time\n", cputime());
- Bprint(&bso, "%d symbols\n", nsymbol);
- Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
- Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
- }
- Bflush(&bso);
-
- errorexit();
-}
-
-static Sym*
-zsym(char *pn, Biobuf *f, Sym *h[])
-{
- int o;
-
- o = BGETC(f);
- if(o < 0 || o >= NSYM || h[o] == nil)
- mangle(pn);
- return h[o];
-}
-
-static void
-zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[])
-{
- int t;
- int32 l;
- Sym *s;
- Auto *u;
-
- t = BGETC(f);
- a->index = D_NONE;
- a->scale = 0;
- if(t & T_INDEX) {
- a->index = BGETC(f);
- a->scale = BGETC(f);
- }
- a->type = D_NONE;
- a->offset = 0;
- if(t & T_OFFSET)
- a->offset = BGETLE4(f);
- a->offset2 = 0;
- if(t & T_OFFSET2) {
- a->offset2 = BGETLE4(f);
- a->type = D_CONST2;
- }
- a->sym = S;
- if(t & T_SYM)
- a->sym = zsym(pn, f, h);
- if(t & T_FCONST) {
- a->ieee.l = BGETLE4(f);
- a->ieee.h = BGETLE4(f);
- a->type = D_FCONST;
- } else
- if(t & T_SCONST) {
- Bread(f, a->scon, NSNAME);
- a->type = D_SCONST;
- }
- if(t & T_TYPE)
- a->type = BGETC(f);
- adrgotype = S;
- if(t & T_GOTYPE)
- adrgotype = zsym(pn, f, h);
-
- t = a->type;
- if(t == D_INDIR+D_GS)
- a->offset += tlsoffset;
-
- s = a->sym;
- if(s == S)
- return;
- if(t != D_AUTO && t != D_PARAM) {
- if(adrgotype)
- s->gotype = adrgotype;
- return;
- }
- l = a->offset;
- for(u=curauto; u; u=u->link) {
- if(u->asym == s)
- if(u->type == t) {
- if(u->aoffset > l)
- u->aoffset = l;
- if(adrgotype)
- u->gotype = adrgotype;
- return;
- }
- }
-
- u = mal(sizeof(*u));
- u->link = curauto;
- curauto = u;
- u->asym = s;
- u->aoffset = l;
- u->type = t;
- u->gotype = adrgotype;
-}
-
-void
-nopout(Prog *p)
-{
- p->as = ANOP;
- p->from.type = D_NONE;
- p->to.type = D_NONE;
-}
-
-void
-ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
-{
- int32 ipc;
- Prog *p;
- int v, o, r, skip;
- Sym *h[NSYM], *s;
- uint32 sig;
- int ntext;
- int32 eof;
- char *name, *x;
- char src[1024];
- Prog *lastp;
-
- lastp = nil;
- ntext = 0;
- eof = Boffset(f) + len;
- src[0] = 0;
- pn = estrdup(pn); // we keep it in Sym* references
-
-newloop:
- memset(h, 0, sizeof(h));
- version++;
- histfrogp = 0;
- ipc = pc;
- skip = 0;
-
-loop:
- if(f->state == Bracteof || Boffset(f) >= eof)
- goto eof;
- o = BGETC(f);
- if(o == Beof)
- goto eof;
- o |= BGETC(f) << 8;
- if(o <= AXXX || o >= ALAST) {
- if(o < 0)
- goto eof;
- diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
- print(" probably not a .%c file\n", thechar);
- errorexit();
- }
-
- if(o == ANAME || o == ASIGNAME) {
- sig = 0;
- if(o == ASIGNAME)
- sig = BGETLE4(f);
- v = BGETC(f); /* type */
- o = BGETC(f); /* sym */
- r = 0;
- if(v == D_STATIC)
- r = version;
- name = Brdline(f, '\0');
- if(name == nil) {
- if(Blinelen(f) > 0) {
- fprint(2, "%s: name too long\n", pn);
- errorexit();
- }
- goto eof;
- }
- x = expandpkg(name, pkg);
- s = lookup(x, r);
- if(x != name)
- free(x);
-
- if(debug['S'] && r == 0)
- sig = 1729;
- if(sig != 0){
- if(s->sig != 0 && s->sig != sig)
- diag("incompatible type signatures "
- "%ux(%s) and %ux(%s) for %s",
- s->sig, s->file, sig, pn, s->name);
- s->sig = sig;
- s->file = pn;
- }
-
- if(debug['W'])
- print(" ANAME %s\n", s->name);
- if(o < 0 || o >= nelem(h))
- mangle(pn);
- h[o] = s;
- if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
- s->type = SXREF;
- if(v == D_FILE) {
- if(s->type != SFILE) {
- histgen++;
- s->type = SFILE;
- s->value = histgen;
- }
- if(histfrogp < MAXHIST) {
- histfrog[histfrogp] = s;
- histfrogp++;
- } else
- collapsefrog(s);
- dwarfaddfrag(s->value, s->name);
- }
- goto loop;
- }
-
- p = mal(sizeof(*p));
- p->as = o;
- p->line = BGETLE4(f);
- p->back = 2;
- zaddr(pn, f, &p->from, h);
- fromgotype = adrgotype;
- zaddr(pn, f, &p->to, h);
-
- if(debug['W'])
- print("%P\n", p);
-
- switch(p->as) {
- case AHISTORY:
- if(p->to.offset == -1) {
- addlib(src, pn);
- histfrogp = 0;
- goto loop;
- }
- if(src[0] == '\0')
- copyhistfrog(src, sizeof src);
- addhist(p->line, D_FILE); /* 'z' */
- if(p->to.offset)
- addhist(p->to.offset, D_FILE1); /* 'Z' */
- savehist(p->line, p->to.offset);
- histfrogp = 0;
- goto loop;
-
- case AEND:
- histtoauto();
- if(cursym != nil && cursym->text)
- cursym->autom = curauto;
- curauto = 0;
- cursym = nil;
- if(Boffset(f) == eof)
- return;
- goto newloop;
-
- case AGLOBL:
- s = p->from.sym;
- if(s->type == 0 || s->type == SXREF) {
- s->type = SBSS;
- s->size = 0;
- }
- if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
- diag("%s: redefinition: %s in %s",
- pn, s->name, TNAME);
- s->type = SBSS;
- s->size = 0;
- }
- if(p->to.offset > s->size)
- s->size = p->to.offset;
- if(p->from.scale & DUPOK)
- s->dupok = 1;
- if(p->from.scale & RODATA)
- s->type = SRODATA;
- else if(p->from.scale & NOPTR)
- s->type = SNOPTRBSS;
- goto loop;
-
- case ADATA:
- // Assume that AGLOBL comes after ADATA.
- // If we've seen an AGLOBL that said this sym was DUPOK,
- // ignore any more ADATA we see, which must be
- // redefinitions.
- s = p->from.sym;
- if(s->dupok) {
-// if(debug['v'])
-// Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
- goto loop;
- }
- if(s->file == nil)
- s->file = pn;
- else if(s->file != pn) {
- diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
- errorexit();
- }
- savedata(s, p, pn);
- unmal(p, sizeof *p);
- goto loop;
-
- case AGOK:
- diag("%s: GOK opcode in %s", pn, TNAME);
- pc++;
- goto loop;
-
- case ATYPE:
- if(skip)
- goto casdef;
- pc++;
- goto loop;
-
- case ATEXT:
- s = p->from.sym;
- if(s->text != nil) {
- if(p->from.scale & DUPOK) {
- skip = 1;
- goto casdef;
- }
- diag("%s: %s: redefinition", pn, s->name);
- return;
- }
- if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
- /* redefinition, so file has probably been seen before */
- if(debug['v'])
- diag("skipping: %s: redefinition: %s", pn, s->name);
- return;
- }
- if(cursym != nil && cursym->text) {
- histtoauto();
- cursym->autom = curauto;
- curauto = 0;
- }
- skip = 0;
- if(etextp)
- etextp->next = s;
- else
- textp = s;
- etextp = s;
- s->text = p;
- cursym = s;
- if(s->type != 0 && s->type != SXREF) {
- if(p->from.scale & DUPOK) {
- skip = 1;
- goto casdef;
- }
- diag("%s: redefinition: %s\n%P", pn, s->name, p);
- }
- s->type = STEXT;
- s->hist = gethist();
- s->value = pc;
- s->args = p->to.offset2;
- lastp = p;
- p->pc = pc++;
- goto loop;
-
- case AFMOVF:
- case AFADDF:
- case AFSUBF:
- case AFSUBRF:
- case AFMULF:
- case AFDIVF:
- case AFDIVRF:
- case AFCOMF:
- case AFCOMFP:
- case AMOVSS:
- case AADDSS:
- case ASUBSS:
- case AMULSS:
- case ADIVSS:
- case ACOMISS:
- case AUCOMISS:
- if(skip)
- goto casdef;
- if(p->from.type == D_FCONST) {
- /* size sb 9 max */
- sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
- s = lookup(literal, 0);
- if(s->type == 0) {
- s->type = SRODATA;
- adduint32(s, ieeedtof(&p->from.ieee));
- s->reachable = 0;
- }
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->from.offset = 0;
- }
- goto casdef;
-
- case AFMOVD:
- case AFADDD:
- case AFSUBD:
- case AFSUBRD:
- case AFMULD:
- case AFDIVD:
- case AFDIVRD:
- case AFCOMD:
- case AFCOMDP:
- case AMOVSD:
- case AADDSD:
- case ASUBSD:
- case AMULSD:
- case ADIVSD:
- case ACOMISD:
- case AUCOMISD:
- if(skip)
- goto casdef;
- if(p->from.type == D_FCONST) {
- /* size sb 18 max */
- sprint(literal, "$%ux.%ux",
- p->from.ieee.l, p->from.ieee.h);
- s = lookup(literal, 0);
- if(s->type == 0) {
- s->type = SRODATA;
- adduint32(s, p->from.ieee.l);
- adduint32(s, p->from.ieee.h);
- s->reachable = 0;
- }
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->from.offset = 0;
- }
- goto casdef;
-
- casdef:
- default:
- if(skip)
- nopout(p);
- p->pc = pc;
- pc++;
-
- if(p->to.type == D_BRANCH)
- p->to.offset += ipc;
- if(lastp == nil) {
- if(p->as != ANOP)
- diag("unexpected instruction: %P", p);
- goto loop;
- }
- lastp->link = p;
- lastp = p;
- goto loop;
- }
-
-eof:
- diag("truncated object file: %s", pn);
-}
-
-Prog*
-prg(void)
-{
- Prog *p;
-
- p = mal(sizeof(Prog));
- *p = zprg;
- return p;
-}
-
-Prog*
-copyp(Prog *q)
-{
- Prog *p;
-
- p = prg();
- *p = *q;
- return p;
-}
-
-Prog*
-appendp(Prog *q)
-{
- Prog *p;
-
- p = prg();
- p->link = q->link;
- q->link = p;
- p->line = q->line;
- return p;
}
diff --git a/src/cmd/8l/optab.c b/src/cmd/8l/optab.c
deleted file mode 100644
index a4c40e8e3..000000000
--- a/src/cmd/8l/optab.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-// Inferno utils/8l/optab.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/optab.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 "l.h"
-
-uchar ynone[] =
-{
- Ynone, Ynone, Zlit, 1,
- 0
-};
-uchar ytext[] =
-{
- Ymb, Yi32, Zpseudo,1,
- 0
-};
-uchar ynop[] =
-{
- Ynone, Ynone, Zpseudo,1,
- Ynone, Yml, Zpseudo,1,
- Ynone, Yrf, Zpseudo,1,
- Yml, Ynone, Zpseudo,1,
- Yrf, Ynone, Zpseudo,1,
- 0
-};
-uchar yfuncdata[] =
-{
- Yi32, Ym, Zpseudo, 0,
- 0
-};
-uchar ypcdata[] =
-{
- Yi32, Yi32, Zpseudo, 0,
- 0,
-};
-uchar yxorb[] =
-{
- Yi32, Yal, Zib_, 1,
- Yi32, Ymb, Zibo_m, 2,
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- 0
-};
-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
-};
-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
-};
-uchar yincb[] =
-{
- Ynone, Ymb, Zo_m, 2,
- 0
-};
-uchar yincl[] =
-{
- Ynone, Yrl, Z_rp, 1,
- Ynone, Yml, Zo_m, 2,
- 0
-};
-uchar ycmpb[] =
-{
- Yal, Yi32, Z_ib, 1,
- Ymb, Yi32, Zm_ibo, 2,
- Ymb, Yrb, Zm_r, 1,
- Yrb, Ymb, Zr_m, 1,
- 0
-};
-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
-};
-uchar yshb[] =
-{
- Yi1, Ymb, Zo_m, 2,
- Yi32, Ymb, Zibo_m, 2,
- Ycx, Ymb, Zo_m, 2,
- 0
-};
-uchar yshl[] =
-{
- Yi1, Yml, Zo_m, 2,
- Yi32, Yml, Zibo_m, 2,
- Ycl, Yml, Zo_m, 2,
- Ycx, Yml, Zo_m, 2,
- 0
-};
-uchar ytestb[] =
-{
- Yi32, Yal, Zib_, 1,
- Yi32, Ymb, Zibo_m, 2,
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- 0
-};
-uchar ytestl[] =
-{
- Yi32, Yax, Zil_, 1,
- Yi32, Yml, Zilo_m, 2,
- Yrl, Yml, Zr_m, 1,
- Yml, Yrl, Zm_r, 1,
- 0
-};
-uchar ymovb[] =
-{
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- Yi32, Yrb, Zib_rp, 1,
- Yi32, Ymb, Zibo_m, 2,
- 0
-};
-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
-};
-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
-};
-uchar ymovq[] =
-{
- Yml, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar ym_rl[] =
-{
- Ym, Yrl, Zm_r, 1,
- 0
-};
-uchar yrl_m[] =
-{
- Yrl, Ym, Zr_m, 1,
- 0
-};
-uchar ymb_rl[] =
-{
- Ymb, Yrl, Zm_r, 1,
- 0
-};
-uchar yml_rl[] =
-{
- Yml, Yrl, Zm_r, 1,
- 0
-};
-uchar yrb_mb[] =
-{
- Yrb, Ymb, Zr_m, 1,
- 0
-};
-uchar yrl_ml[] =
-{
- Yrl, Yml, Zr_m, 1,
- 0
-};
-uchar yml_mb[] =
-{
- Yrb, Ymb, Zr_m, 1,
- Ymb, Yrb, Zm_r, 1,
- 0
-};
-uchar yxchg[] =
-{
- Yax, Yrl, Z_rp, 1,
- Yrl, Yax, Zrp_, 1,
- Yrl, Yml, Zr_m, 1,
- Yml, Yrl, Zm_r, 1,
- 0
-};
-uchar ydivl[] =
-{
- Yml, Ynone, Zm_o, 2,
- 0
-};
-uchar ydivb[] =
-{
- Ymb, Ynone, Zm_o, 2,
- 0
-};
-uchar yimul[] =
-{
- Yml, Ynone, Zm_o, 2,
- Yi8, Yrl, Zib_rr, 1,
- Yi32, Yrl, Zil_rr, 1,
- 0
-};
-uchar ybyte[] =
-{
- Yi32, Ynone, Zbyte, 1,
- 0
-};
-uchar yin[] =
-{
- Yi32, Ynone, Zib_, 1,
- Ynone, Ynone, Zlit, 1,
- 0
-};
-uchar yint[] =
-{
- Yi32, Ynone, Zib_, 1,
- 0
-};
-uchar ypushl[] =
-{
- Yrl, Ynone, Zrp_, 1,
- Ym, Ynone, Zm_o, 2,
- Yi8, Ynone, Zib_, 1,
- Yi32, Ynone, Zil_, 1,
- 0
-};
-uchar ypopl[] =
-{
- Ynone, Yrl, Z_rp, 1,
- Ynone, Ym, Zo_m, 2,
- 0
-};
-uchar ybswap[] =
-{
- Ynone, Yrl, Z_rp, 1,
- 0,
-};
-uchar yscond[] =
-{
- Ynone, Ymb, Zo_m, 2,
- 0
-};
-uchar yjcond[] =
-{
- Ynone, Ybr, Zbr, 0,
- Yi0, Ybr, Zbr, 0,
- Yi1, Ybr, Zbr, 1,
- 0
-};
-uchar yloop[] =
-{
- Ynone, Ybr, Zloop, 1,
- 0
-};
-uchar ycall[] =
-{
- Ynone, Yml, Zo_m, 0,
- Yrx, Yrx, Zo_m, 2,
- Ynone, Ycol, Zcallind, 2,
- Ynone, Ybr, Zcall, 0,
- Ynone, Yi32, Zcallcon, 1,
- 0
-};
-uchar yjmp[] =
-{
- Ynone, Yml, Zo_m, 2,
- Ynone, Ybr, Zjmp, 0,
- Ynone, Yi32, Zjmpcon, 1,
- 0
-};
-
-uchar yfmvd[] =
-{
- Ym, Yf0, Zm_o, 2,
- Yf0, Ym, Zo_m, 2,
- Yrf, Yf0, Zm_o, 2,
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfmvdp[] =
-{
- Yf0, Ym, Zo_m, 2,
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfmvf[] =
-{
- Ym, Yf0, Zm_o, 2,
- Yf0, Ym, Zo_m, 2,
- 0
-};
-uchar yfmvx[] =
-{
- Ym, Yf0, Zm_o, 2,
- 0
-};
-uchar yfmvp[] =
-{
- Yf0, Ym, Zo_m, 2,
- 0
-};
-uchar yfcmv[] =
-{
- Yrf, Yf0, Zm_o, 2,
- 0
-};
-uchar yfadd[] =
-{
- Ym, Yf0, Zm_o, 2,
- Yrf, Yf0, Zm_o, 2,
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfaddp[] =
-{
- Yf0, Yrf, Zo_m, 2,
- 0
-};
-uchar yfxch[] =
-{
- Yf0, Yrf, Zo_m, 2,
- Yrf, Yf0, Zm_o, 2,
- 0
-};
-uchar ycompp[] =
-{
- Yf0, Yrf, Zo_m, 2, /* botch is really f0,f1 */
- 0
-};
-uchar ystsw[] =
-{
- Ynone, Ym, Zo_m, 2,
- Ynone, Yax, Zlit, 1,
- 0
-};
-uchar ystcw[] =
-{
- Ynone, Ym, Zo_m, 2,
- Ym, Ynone, Zm_o, 2,
- 0
-};
-uchar ysvrs[] =
-{
- Ynone, Ym, Zo_m, 2,
- Ym, Ynone, Zm_o, 2,
- 0
-};
-uchar ymskb[] =
-{
- Yxr, Yrl, Zm_r_xm, 2,
- Ymr, Yrl, Zm_r_xm, 1,
- 0
-};
-uchar yxm[] =
-{
- Yxm, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxcvm1[] =
-{
- Yxm, Yxr, Zm_r_xm, 2,
- Yxm, Ymr, Zm_r_xm, 2,
- 0
-};
-uchar yxcvm2[] =
-{
- Yxm, Yxr, Zm_r_xm, 2,
- Ymm, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar yxmq[] =
-{
- Yxm, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar yxr[] =
-{
- Yxr, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxr_ml[] =
-{
- Yxr, Yml, Zr_m_xm, 1,
- 0
-};
-uchar yxcmp[] =
-{
- Yxm, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxcmpi[] =
-{
- Yxm, Yxr, Zm_r_i_xm, 2,
- 0
-};
-uchar yxmov[] =
-{
- Yxm, Yxr, Zm_r_xm, 1,
- Yxr, Yxm, Zr_m_xm, 1,
- 0
-};
-uchar yxcvfl[] =
-{
- Yxm, Yrl, Zm_r_xm, 1,
- 0
-};
-uchar yxcvlf[] =
-{
- Yml, Yxr, Zm_r_xm, 1,
- 0
-};
-uchar yxcvfq[] =
-{
- Yxm, Yrl, Zm_r_xm, 2,
- 0
-};
-uchar yxcvqf[] =
-{
- Yml, Yxr, Zm_r_xm, 2,
- 0
-};
-uchar yxrrl[] =
-{
- Yxr, Yrl, Zm_r, 1,
- 0
-};
-uchar yprefetch[] =
-{
- Ym, Ynone, Zm_o, 2,
- 0,
-};
-uchar yaes[] =
-{
- Yxm, Yxr, Zlitm_r, 2,
- 0
-};
-uchar yinsrd[] =
-{
- Yml, Yxr, Zibm_r, 2,
- 0
-};
-uchar ymshufb[] =
-{
- Yxm, Yxr, Zm2_r, 2,
- 0
-};
-
-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 },
- { AGOK },
- { AHISTORY },
- { 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) },
- { ANAME },
- { ANEGB, yscond, Px, 0xf6,(03) },
- { ANEGL, yscond, Px, 0xf7,(03) },
- { ANEGW, yscond, Pe, 0xf7,(03) },
- { ANOP, ynop, Px,0,0 },
- { ANOTB, yscond, Px, 0xf6,(02) },
- { ANOTL, yscond, Px, 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 },
- { 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, 0x96,(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 },
- { ADYNT_ },
- { AINIT_ },
- { ASIGNAME },
- { ACMPXCHGB, yrb_mb, Pm, 0xb0 },
- { ACMPXCHGL, yrl_ml, Pm, 0xb1 },
- { ACMPXCHGW, yrl_ml, Pm, 0xb1 },
- { ACMPXCHG8B, yscond, Pm, 0xc7,(01) },
-
- { 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 },
- { 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 },
-
- { 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 },
-
- 0
-};
diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c
deleted file mode 100644
index 1eaf78fe0..000000000
--- a/src/cmd/8l/pass.c
+++ /dev/null
@@ -1,858 +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.
-
-// Code and data passes.
-
-#include "l.h"
-#include "../ld/lib.h"
-#include "../../pkg/runtime/stack.h"
-
-static void xfol(Prog*, Prog**);
-
-Prog*
-brchain(Prog *p)
-{
- int i;
-
- for(i=0; i<20; i++) {
- if(p == P || p->as != AJMP)
- return p;
- p = p->pcond;
- }
- return P;
-}
-
-void
-follow(void)
-{
- Prog *firstp, *lastp;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f follow\n", cputime());
- Bflush(&bso);
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- firstp = prg();
- lastp = firstp;
- xfol(cursym->text, &lastp);
- lastp->link = nil;
- cursym->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 void
-xfol(Prog *p, Prog **last)
-{
- Prog *q;
- int i;
- enum as a;
-
-loop:
- if(p == P)
- return;
- if(p->as == AJMP)
- if((q = p->pcond) != P && 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 == P)
- 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 == P || q->pcond->mark)
- continue;
- if(a == ACALL || a == ALOOP)
- continue;
- for(;;) {
- if(p->as == ANOP) {
- p = p->link;
- continue;
- }
- q = copyp(p);
- p = p->link;
- q->mark = 1;
- (*last)->link = q;
- *last = q;
- if(q->as != a || q->pcond == P || q->pcond->mark)
- continue;
-
- q->as = relinv(q->as);
- p = q->pcond;
- q->pcond = q->link;
- q->link = p;
- xfol(q->link, last);
- p = q->link;
- if(p->mark)
- return;
- goto loop;
- }
- } /* */
- q = prg();
- q->as = AJMP;
- q->line = p->line;
- q->to.type = D_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 != P && a != ACALL) {
- /*
- * some kind of conditional branch.
- * recurse to follow one path.
- * continue loop on the other.
- */
- if((q = brchain(p->pcond)) != P)
- p->pcond = q;
- if((q = brchain(p->link)) != P)
- p->link = q;
- if(p->from.type == D_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(p->link, last);
- if(p->pcond->mark)
- return;
- p = p->pcond;
- goto loop;
- }
- p = p->link;
- goto loop;
-}
-
-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;
- }
- diag("unknown relation: %s in %s", anames[a], TNAME);
- return a;
-}
-
-void
-patch(void)
-{
- int32 c;
- Prog *p, *q;
- Sym *s;
- int32 vexit;
- Sym *plan9_tos;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f mkfwd\n", cputime());
- Bflush(&bso);
- mkfwd();
- if(debug['v'])
- Bprint(&bso, "%5.2f patch\n", cputime());
- Bflush(&bso);
- s = lookup("exit", 0);
- vexit = s->value;
-
- plan9_tos = S;
- if(HEADTYPE == Hplan9x32)
- plan9_tos = lookup("_tos", 0);
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- if(HEADTYPE == Hwindows) {
- // Convert
- // op n(GS), reg
- // to
- // MOVL 0x14(FS), reg
- // op n(reg), reg
- // The purpose of this patch is to fix some accesses
- // to extern register variables (TLS) on Windows, as
- // a different method is used to access them.
- if(p->from.type == D_INDIR+D_GS
- && p->to.type >= D_AX && p->to.type <= D_DI) {
- q = appendp(p);
- q->from = p->from;
- q->from.type = D_INDIR + p->to.type;
- q->to = p->to;
- q->as = p->as;
- p->as = AMOVL;
- p->from.type = D_INDIR+D_FS;
- p->from.offset = 0x14;
- }
- }
- if(HEADTYPE == Hlinux) {
- // Running binaries under Xen requires using
- // MOVL 0(GS), reg
- // and then off(reg) instead of saying off(GS) directly
- // when the offset is negative.
- // In external mode we just produce a reloc.
- if(p->from.type == D_INDIR+D_GS && p->from.offset < 0
- && p->to.type >= D_AX && p->to.type <= D_DI) {
- if(linkmode != LinkExternal) {
- q = appendp(p);
- q->from = p->from;
- q->from.type = D_INDIR + p->to.type;
- q->to = p->to;
- q->as = p->as;
- p->as = AMOVL;
- p->from.type = D_INDIR+D_GS;
- p->from.offset = 0;
- } else {
- // Add signals to relocate.
- p->from.index = D_GS;
- p->from.scale = 1;
- }
- }
- }
- if(HEADTYPE == Hplan9x32) {
- if(p->from.type == D_INDIR+D_GS
- && p->to.type >= D_AX && p->to.type <= D_DI) {
- q = appendp(p);
- q->from = p->from;
- q->from.type = D_INDIR + p->to.type;
- q->to = p->to;
- q->as = p->as;
- p->as = AMOVL;
- p->from.type = D_EXTERN;
- p->from.sym = plan9_tos;
- p->from.offset = 0;
- }
- }
- if((p->as == ACALL && p->to.type != D_BRANCH) || (p->as == AJMP && p->to.type != D_BRANCH) || (p->as == ARET && p->to.sym != nil)) {
- s = p->to.sym;
- if(p->to.type == D_INDIR+D_ADDR) {
- /* skip check if this is an indirect call (CALL *symbol(SB)) */
- continue;
- } else if(s) {
- if(debug['c'])
- Bprint(&bso, "%s calls %s\n", TNAME, s->name);
- if((s->type&SMASK) != STEXT) {
- /* diag prints TNAME first */
- diag("undefined: %s", s->name);
- s->type = STEXT;
- s->value = vexit;
- continue; // avoid more error messages
- }
- if(s->text == nil)
- continue;
- p->to.type = D_BRANCH;
- p->to.offset = s->text->pc;
- p->pcond = s->text;
- continue;
- }
- }
- if(p->to.type != D_BRANCH)
- continue;
- c = p->to.offset;
- for(q = cursym->text; q != P;) {
- if(c == q->pc)
- break;
- if(q->forwd != P && c >= q->forwd->pc)
- q = q->forwd;
- else
- q = q->link;
- }
- if(q == P) {
- diag("branch out of range in %s (%#ux)\n%P [%s]",
- TNAME, c, p, p->to.sym ? p->to.sym->name : "<nil>");
- p->to.type = D_NONE;
- }
- p->pcond = q;
- }
- }
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(cursym->text == nil || cursym->p != nil)
- continue;
-
- for(p = cursym->text; p != P; p = p->link) {
- p->mark = 0; /* initialization for follow */
- if(p->pcond != P) {
- p->pcond = brloop(p->pcond);
- if(p->pcond != P)
- if(p->to.type == D_BRANCH)
- p->to.offset = p->pcond->pc;
- }
- }
- }
-}
-
-Prog*
-brloop(Prog *p)
-{
- int c;
- Prog *q;
-
- c = 0;
- for(q = p; q != P; q = q->pcond) {
- if(q->as != AJMP)
- break;
- c++;
- if(c >= 5000)
- return P;
- }
- return q;
-}
-
-static Prog* load_g_cx(Prog*);
-static Prog* stacksplit(Prog*, int32, Prog**);
-
-static Sym *plan9_tos;
-static Prog *pmorestack;
-static Sym *symmorestack;
-
-void
-dostkoff(void)
-{
- Prog *p, *q;
- int32 autoffset, deltasp;
- int a;
-
- pmorestack = P;
- symmorestack = lookup("runtime.morestack", 0);
-
- if(symmorestack->type != STEXT)
- diag("runtime.morestack not defined");
- else {
- pmorestack = symmorestack->text;
- symmorestack->text->from.scale |= NOSPLIT;
- }
-
- plan9_tos = S;
- if(HEADTYPE == Hplan9x32)
- plan9_tos = lookup("_tos", 0);
-
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(cursym->text == nil || cursym->text->link == nil)
- continue;
-
- p = cursym->text;
- autoffset = p->to.offset;
- if(autoffset < 0)
- autoffset = 0;
-
- q = P;
-
- if(!(p->from.scale & NOSPLIT) || (p->from.scale & WRAPPER)) {
- p = appendp(p);
- p = load_g_cx(p); // load g into CX
- }
- if(!(cursym->text->from.scale & NOSPLIT))
- p = stacksplit(p, autoffset, &q); // emit split check
-
- if(autoffset) {
- p = appendp(p);
- p->as = AADJSP;
- p->from.type = D_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(p);
- p->as = ANOP;
- p->spadj = -PtrSize;
- p = appendp(p);
- p->as = ANOP;
- p->spadj = PtrSize;
- }
- if(q != P)
- q->pcond = p;
- deltasp = autoffset;
-
- if(cursym->text->from.scale & WRAPPER) {
- // g->panicwrap += autoffset + PtrSize;
- p = appendp(p);
- p->as = AADDL;
- p->from.type = D_CONST;
- p->from.offset = autoffset + PtrSize;
- p->to.type = D_INDIR+D_CX;
- p->to.offset = 2*PtrSize;
- }
-
- if(debug['Z'] && autoffset && !(cursym->text->from.scale&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(p);
- p->as = AMOVL;
- p->from.type = D_SP;
- p->to.type = D_DI;
-
- p = appendp(p);
- p->as = AMOVL;
- p->from.type = D_CONST;
- p->from.offset = autoffset/4;
- p->to.type = D_CX;
-
- p = appendp(p);
- p->as = AMOVL;
- p->from.type = D_CONST;
- p->from.offset = 0;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = AREP;
-
- p = appendp(p);
- p->as = ASTOSL;
- }
-
- for(; p != P; p = p->link) {
- a = p->from.type;
- if(a == D_AUTO)
- p->from.offset += deltasp;
- if(a == D_PARAM)
- p->from.offset += deltasp + 4;
- a = p->to.type;
- if(a == D_AUTO)
- p->to.offset += deltasp;
- if(a == D_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)
- diag("unbalanced PUSH/POP");
-
- if(cursym->text->from.scale & WRAPPER) {
- p = load_g_cx(p);
- p = appendp(p);
- // g->panicwrap -= autoffset + PtrSize;
- p->as = ASUBL;
- p->from.type = D_CONST;
- p->from.offset = autoffset + PtrSize;
- p->to.type = D_INDIR+D_CX;
- p->to.offset = 2*PtrSize;
- p = appendp(p);
- p->as = ARET;
- }
-
- if(autoffset) {
- p->as = AADJSP;
- p->from.type = D_CONST;
- p->from.offset = -autoffset;
- p->spadj = -autoffset;
- p = appendp(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(Prog *p)
-{
- switch(HEADTYPE) {
- case Hwindows:
- p->as = AMOVL;
- p->from.type = D_INDIR+D_FS;
- p->from.offset = 0x14;
- p->to.type = D_CX;
-
- p = appendp(p);
- p->as = AMOVL;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 0;
- p->to.type = D_CX;
- break;
-
- case Hlinux:
- if(linkmode != LinkExternal) {
- p->as = AMOVL;
- p->from.type = D_INDIR+D_GS;
- p->from.offset = 0;
- p->to.type = D_CX;
-
- p = appendp(p);
- p->as = AMOVL;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = tlsoffset + 0;
- p->to.type = D_CX;
- } else {
- p->as = AMOVL;
- p->from.type = D_INDIR+D_GS;
- p->from.offset = tlsoffset + 0;
- p->to.type = D_CX;
- p->from.index = D_GS;
- p->from.scale = 1;
- }
- break;
-
- case Hplan9x32:
- p->as = AMOVL;
- p->from.type = D_EXTERN;
- p->from.sym = plan9_tos;
- p->to.type = D_CX;
-
- p = appendp(p);
- p->as = AMOVL;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = tlsoffset + 0;
- p->to.type = D_CX;
- break;
-
- default:
- p->as = AMOVL;
- p->from.type = D_INDIR+D_GS;
- p->from.offset = tlsoffset + 0;
- p->to.type = D_CX;
- }
- 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(Prog *p, int32 framesize, Prog **jmpok)
-{
- Prog *q, *q1;
- int arg;
-
- if(debug['K']) {
- // 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(p);
- p->as = ACMPL;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 4;
- p->to.type = D_SP;
-
- p = appendp(p);
- p->as = AJCC;
- p->to.type = D_BRANCH;
- p->to.offset = 4;
- q1 = p;
-
- p = appendp(p);
- p->as = AINT;
- p->from.type = D_CONST;
- p->from.offset = 3;
-
- p = appendp(p);
- p->as = ANOP;
- q1->pcond = p;
- }
- q1 = P;
-
- if(framesize <= StackSmall) {
- // small stack: SP <= stackguard
- // CMPL SP, stackguard
- p = appendp(p);
- p->as = ACMPL;
- p->from.type = D_SP;
- p->to.type = D_INDIR+D_CX;
- } else if(framesize <= StackBig) {
- // large stack: SP-framesize <= stackguard-StackSmall
- // LEAL -(framesize-StackSmall)(SP), AX
- // CMPL AX, stackguard
- p = appendp(p);
- p->as = ALEAL;
- p->from.type = D_INDIR+D_SP;
- p->from.offset = -(framesize-StackSmall);
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACMPL;
- p->from.type = D_AX;
- p->to.type = D_INDIR+D_CX;
- } 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(p);
- p->as = AMOVL;
- p->from.type = D_INDIR+D_CX;
- p->from.offset = 0;
- p->to.type = D_SI;
-
- p = appendp(p);
- p->as = ACMPL;
- p->from.type = D_SI;
- p->to.type = D_CONST;
- p->to.offset = (uint32)StackPreempt;
-
- p = appendp(p);
- p->as = AJEQ;
- p->to.type = D_BRANCH;
- q1 = p;
-
- p = appendp(p);
- p->as = ALEAL;
- p->from.type = D_INDIR+D_SP;
- p->from.offset = StackGuard;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ASUBL;
- p->from.type = D_SI;
- p->from.offset = 0;
- p->to.type = D_AX;
-
- p = appendp(p);
- p->as = ACMPL;
- p->from.type = D_AX;
- p->to.type = D_CONST;
- p->to.offset = framesize+(StackGuard-StackSmall);
- }
-
- // common
- p = appendp(p);
- p->as = AJHI;
- p->to.type = D_BRANCH;
- p->to.offset = 4;
- q = p;
-
- p = appendp(p); // save frame size in DI
- p->as = AMOVL;
- p->to.type = D_DI;
- p->from.type = D_CONST;
-
- // If we ask for more stack, we'll get a minimum of StackMin bytes.
- // We need a stack frame large enough to hold the top-of-stack data,
- // the function arguments+results, our caller's PC, our frame,
- // a word for the return PC of the next call, and then the StackLimit bytes
- // that must be available on entry to any function called from a function
- // that did a stack check. If StackMin is enough, don't ask for a specific
- // amount: then we can use the custom functions and save a few
- // instructions.
- if(StackTop + cursym->text->to.offset2 + PtrSize + framesize + PtrSize + StackLimit >= StackMin)
- p->from.offset = (framesize+7) & ~7LL;
-
- arg = cursym->text->to.offset2;
- if(arg == 1) // special marker for known 0
- arg = 0;
- if(arg&3)
- diag("misaligned argument size in stack split");
- p = appendp(p); // save arg size in AX
- p->as = AMOVL;
- p->to.type = D_AX;
- p->from.type = D_CONST;
- p->from.offset = arg;
-
- p = appendp(p);
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = pmorestack;
- p->to.sym = symmorestack;
-
- p = appendp(p);
- p->as = AJMP;
- p->to.type = D_BRANCH;
- p->pcond = cursym->text->link;
-
- if(q != P)
- q->pcond = p->link;
- if(q1 != P)
- q1->pcond = q->link;
-
- *jmpok = q;
- return p;
-}
-
-int32
-atolwhex(char *s)
-{
- int32 n;
- int f;
-
- n = 0;
- f = 0;
- while(*s == ' ' || *s == '\t')
- s++;
- if(*s == '-' || *s == '+') {
- if(*s++ == '-')
- f = 1;
- while(*s == ' ' || *s == '\t')
- s++;
- }
- if(s[0]=='0' && s[1]){
- if(s[1]=='x' || s[1]=='X'){
- s += 2;
- for(;;){
- if(*s >= '0' && *s <= '9')
- n = n*16 + *s++ - '0';
- else if(*s >= 'a' && *s <= 'f')
- n = n*16 + *s++ - 'a' + 10;
- else if(*s >= 'A' && *s <= 'F')
- n = n*16 + *s++ - 'A' + 10;
- else
- break;
- }
- } else
- while(*s >= '0' && *s <= '7')
- n = n*8 + *s++ - '0';
- } else
- while(*s >= '0' && *s <= '9')
- n = n*10 + *s++ - '0';
- if(f)
- n = -n;
- return n;
-}
diff --git a/src/cmd/8l/prof.c b/src/cmd/8l/prof.c
deleted file mode 100644
index d99c5e408..000000000
--- a/src/cmd/8l/prof.c
+++ /dev/null
@@ -1,173 +0,0 @@
-// Inferno utils/8l/obj.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8l/obj.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.
-
-// Profiling.
-
-#include "l.h"
-#include "../ld/lib.h"
-
-void
-doprof1(void)
-{
-#ifdef NOTDEF // TODO(rsc)
- Sym *s;
- int32 n;
- Prog *p, *q;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f profile 1\n", cputime());
- Bflush(&bso);
- s = lookup("__mcount", 0);
- n = 1;
- for(p = firstp->link; p != P; p = p->link) {
- if(p->as == ATEXT) {
- q = prg();
- q->line = p->line;
- q->link = datap;
- datap = q;
- q->as = ADATA;
- q->from.type = D_EXTERN;
- q->from.offset = n*4;
- q->from.sym = s;
- q->from.scale = 4;
- q->to = p->from;
- q->to.type = D_CONST;
-
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = AADDL;
- p->from.type = D_CONST;
- p->from.offset = 1;
- p->to.type = D_EXTERN;
- p->to.sym = s;
- p->to.offset = n*4 + 4;
-
- n += 2;
- continue;
- }
- }
- q = prg();
- q->line = 0;
- q->link = datap;
- datap = q;
-
- q->as = ADATA;
- q->from.type = D_EXTERN;
- q->from.sym = s;
- q->from.scale = 4;
- q->to.type = D_CONST;
- q->to.offset = n;
-
- s->type = SBSS;
- s->size = n*4;
-#endif
-}
-
-void
-doprof2(void)
-{
- Sym *s2, *s4;
- Prog *p, *q, *ps2, *ps4;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f profile 2\n", cputime());
- Bflush(&bso);
-
- s2 = lookup("_profin", 0);
- s4 = lookup("_profout", 0);
- if(s2->type != STEXT || s4->type != STEXT) {
- diag("_profin/_profout not defined");
- return;
- }
-
- ps2 = P;
- ps4 = P;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
- if(p->from.sym == s2) {
- p->from.scale = 1;
- ps2 = p;
- }
- if(p->from.sym == s4) {
- p->from.scale = 1;
- ps4 = p;
- }
- }
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
-
- if(p->from.scale & NOPROF) /* dont profile */
- continue;
-
- /*
- * JMPL profin
- */
- q = prg();
- q->line = p->line;
- q->pc = p->pc;
- q->link = p->link;
- p->link = q;
- p = q;
- p->as = ACALL;
- p->to.type = D_BRANCH;
- p->pcond = ps2;
- p->to.sym = s2;
-
- for(; p; p=p->link) {
- if(p->as == ARET) {
- /*
- * RET
- */
- q = prg();
- q->as = ARET;
- q->from = p->from;
- q->to = p->to;
- q->link = p->link;
- p->link = q;
-
- /*
- * JAL profout
- */
- p->as = ACALL;
- p->from = zprg.from;
- p->to = zprg.to;
- p->to.type = D_BRANCH;
- p->pcond = ps4;
- p->to.sym = s4;
-
- p = q;
- }
- }
- }
-}
diff --git a/src/cmd/8l/span.c b/src/cmd/8l/span.c
deleted file mode 100644
index acf973cab..000000000
--- a/src/cmd/8l/span.c
+++ /dev/null
@@ -1,1507 +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 "l.h"
-#include "../ld/lib.h"
-#include "../ld/elf.h"
-
-static int32 vaddr(Adr*, Reloc*);
-
-void
-span1(Sym *s)
-{
- Prog *p, *q;
- int32 c, v, loop;
- uchar *bp;
- int n, m, i;
-
- cursym = s;
-
- for(p = s->text; p != P; p = p->link) {
- p->back = 2; // use short branches first time through
- if((q = p->pcond) != P && (q->back & 2))
- p->back |= 1; // backward jump
-
- if(p->as == AADJSP) {
- p->to.type = D_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 != P; p = p->link) {
- p->pc = c;
-
- // process forward jumps to p
- for(q = p->comefrom; q != P; 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 = P;
-
- asmins(p);
- p->pc = c;
- m = andptr-and;
- symgrow(s, p->pc+m);
- memmove(s->p+p->pc, and, m);
- p->mark = m;
- c += m;
- }
- if(++n > 20) {
- diag("span must be looping");
- errorexit();
- }
- } while(loop);
- s->size = c;
-
- if(debug['a'] > 1) {
- print("span1 %s %d (%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%+d\n", r->off, r->siz, r->sym->name, r->add);
- }
- }
-}
-
-void
-span(void)
-{
- Prog *p, *q;
- int32 v;
- int n;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f span\n", cputime());
-
- // NOTE(rsc): If we get rid of the globals we should
- // be able to parallelize these iterations.
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- if(cursym->text == nil || cursym->text->link == nil)
- continue;
-
- // TODO: move into span1
- for(p = cursym->text; p != P; p = p->link) {
- n = 0;
- if(p->to.type == D_BRANCH)
- if(p->pcond == P)
- p->pcond = p;
- if((q = p->pcond) != P)
- if(q->back != 2)
- n = 1;
- p->back = n;
- if(p->as == AADJSP) {
- p->to.type = D_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;
- }
- }
- span1(cursym);
- }
-}
-
-void
-xdefine(char *p, int t, int32 v)
-{
- Sym *s;
-
- s = lookup(p, 0);
- s->type = t;
- s->value = v;
- s->reachable = 1;
- s->special = 1;
-}
-
-void
-instinit(void)
-{
- int i;
-
- for(i=1; optab[i].as; i++)
- if(i != optab[i].as) {
- diag("phase error in optab: at %A found %A", i, optab[i].as);
- errorexit();
- }
- maxop = 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<D_NONE; i++) {
- reg[i] = -1;
- if(i >= D_AL && i <= D_BH)
- reg[i] = (i-D_AL) & 7;
- if(i >= D_AX && i <= D_DI)
- reg[i] = (i-D_AX) & 7;
- if(i >= D_F0 && i <= D_F0+7)
- reg[i] = (i-D_F0) & 7;
- if(i >= D_X0 && i <= D_X0+7)
- reg[i] = (i-D_X0) & 7;
- }
-}
-
-int
-prefixof(Adr *a)
-{
- switch(a->type) {
- case D_INDIR+D_CS:
- return 0x2e;
- case D_INDIR+D_DS:
- return 0x3e;
- case D_INDIR+D_ES:
- return 0x26;
- case D_INDIR+D_FS:
- return 0x64;
- case D_INDIR+D_GS:
- return 0x65;
- }
- return 0;
-}
-
-int
-oclass(Adr *a)
-{
- int32 v;
-
- if((a->type >= D_INDIR && a->type < 2*D_INDIR) || a->index != D_NONE) {
- if(a->index != D_NONE && a->scale == 0) {
- if(a->type == D_ADDR) {
- switch(a->index) {
- case D_EXTERN:
- case D_STATIC:
- return Yi32;
- case D_AUTO:
- case D_PARAM:
- return Yiauto;
- }
- return Yxxx;
- }
- //if(a->type == D_INDIR+D_ADDR)
- // print("*Ycol\n");
- return Ycol;
- }
- return Ym;
- }
- switch(a->type)
- {
- case D_AL:
- return Yal;
-
- case D_AX:
- return Yax;
-
- case D_CL:
- case D_DL:
- case D_BL:
- case D_AH:
- case D_CH:
- case D_DH:
- case D_BH:
- return Yrb;
-
- case D_CX:
- return Ycx;
-
- case D_DX:
- case D_BX:
- return Yrx;
-
- case D_SP:
- case D_BP:
- case D_SI:
- case D_DI:
- return Yrl;
-
- case D_F0+0:
- return Yf0;
-
- case D_F0+1:
- case D_F0+2:
- case D_F0+3:
- case D_F0+4:
- case D_F0+5:
- case D_F0+6:
- case D_F0+7:
- return Yrf;
-
- case D_X0+0:
- case D_X0+1:
- case D_X0+2:
- case D_X0+3:
- case D_X0+4:
- case D_X0+5:
- case D_X0+6:
- case D_X0+7:
- return Yxr;
-
- case D_NONE:
- return Ynone;
-
- case D_CS: return Ycs;
- case D_SS: return Yss;
- case D_DS: return Yds;
- case D_ES: return Yes;
- case D_FS: return Yfs;
- case D_GS: return Ygs;
-
- case D_GDTR: return Ygdtr;
- case D_IDTR: return Yidtr;
- case D_LDTR: return Yldtr;
- case D_MSW: return Ymsw;
- case D_TASK: return Ytask;
-
- case D_CR+0: return Ycr0;
- case D_CR+1: return Ycr1;
- case D_CR+2: return Ycr2;
- case D_CR+3: return Ycr3;
- case D_CR+4: return Ycr4;
- case D_CR+5: return Ycr5;
- case D_CR+6: return Ycr6;
- case D_CR+7: return Ycr7;
-
- case D_DR+0: return Ydr0;
- case D_DR+1: return Ydr1;
- case D_DR+2: return Ydr2;
- case D_DR+3: return Ydr3;
- case D_DR+4: return Ydr4;
- case D_DR+5: return Ydr5;
- case D_DR+6: return Ydr6;
- case D_DR+7: return Ydr7;
-
- case D_TR+0: return Ytr0;
- case D_TR+1: return Ytr1;
- case D_TR+2: return Ytr2;
- case D_TR+3: return Ytr3;
- case D_TR+4: return Ytr4;
- case D_TR+5: return Ytr5;
- case D_TR+6: return Ytr6;
- case D_TR+7: return Ytr7;
-
- case D_EXTERN:
- case D_STATIC:
- case D_AUTO:
- case D_PARAM:
- return Ym;
-
- case D_CONST:
- case D_CONST2:
- case D_ADDR:
- if(a->sym == S) {
- v = a->offset;
- if(v == 0)
- return Yi0;
- if(v == 1)
- return Yi1;
- if(v >= -128 && v <= 127)
- return Yi8;
- }
- return Yi32;
-
- case D_BRANCH:
- return Ybr;
- }
- return Yxxx;
-}
-
-void
-asmidx(int scale, int index, int base)
-{
- int i;
-
- switch(index) {
- default:
- goto bad;
-
- case D_NONE:
- i = 4 << 3;
- goto bas;
-
- case D_AX:
- case D_CX:
- case D_DX:
- case D_BX:
- case D_BP:
- case D_SI:
- case D_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 D_NONE: /* must be mod=00 */
- i |= 5;
- break;
- case D_AX:
- case D_CX:
- case D_DX:
- case D_BX:
- case D_SP:
- case D_BP:
- case D_SI:
- case D_DI:
- i |= reg[base];
- break;
- }
- *andptr++ = i;
- return;
-bad:
- diag("asmidx: bad address %d,%d,%d", scale, index, base);
- *andptr++ = 0;
- return;
-}
-
-static void
-put4(int32 v)
-{
- andptr[0] = v;
- andptr[1] = v>>8;
- andptr[2] = v>>16;
- andptr[3] = v>>24;
- andptr += 4;
-}
-
-static void
-relput4(Prog *p, Adr *a)
-{
- vlong v;
- Reloc rel, *r;
-
- v = vaddr(a, &rel);
- if(rel.siz != 0) {
- if(rel.siz != 4)
- diag("bad reloc");
- r = addrel(cursym);
- *r = rel;
- r->off = p->pc + andptr - and;
- }
- put4(v);
-}
-
-int32
-symaddr(Sym *s)
-{
- if(!s->reachable)
- diag("unreachable symbol in symaddr - %s", s->name);
- return s->value;
-}
-
-static int32
-vaddr(Adr *a, Reloc *r)
-{
- int t;
- int32 v;
- Sym *s;
-
- if(r != nil)
- memset(r, 0, sizeof *r);
-
- t = a->type;
- v = a->offset;
- if(t == D_ADDR)
- t = a->index;
- switch(t) {
- case D_STATIC:
- case D_EXTERN:
- s = a->sym;
- if(s != nil) {
- if(!s->reachable)
- sysfatal("unreachable symbol in vaddr - %s", s->name);
- if(r == nil) {
- diag("need reloc for %D", a);
- errorexit();
- }
- r->type = D_ADDR;
- r->siz = 4;
- r->off = -1;
- r->sym = s;
- r->add = v;
- v = 0;
- }
- }
- return v;
-}
-
-static int
-istls(Adr *a)
-{
- if(HEADTYPE == Hlinux)
- return a->index == D_GS;
- return a->type == D_INDIR+D_GS;
-}
-
-void
-asmand(Adr *a, int r)
-{
- int32 v;
- int t, scale;
- Reloc rel;
-
- v = a->offset;
- t = a->type;
- rel.siz = 0;
- if(a->index != D_NONE && a->index != D_FS && a->index != D_GS) {
- if(t < D_INDIR || t >= 2*D_INDIR) {
- switch(t) {
- default:
- goto bad;
- case D_STATIC:
- case D_EXTERN:
- t = D_NONE;
- v = vaddr(a, &rel);
- break;
- case D_AUTO:
- case D_PARAM:
- t = D_SP;
- break;
- }
- } else
- t -= D_INDIR;
-
- if(t == D_NONE) {
- *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- goto putrelv;
- }
- if(v == 0 && rel.siz == 0 && t != D_BP) {
- *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- return;
- }
- if(v >= -128 && v < 128 && rel.siz == 0) {
- *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- *andptr++ = v;
- return;
- }
- *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
- asmidx(a->scale, a->index, t);
- goto putrelv;
- }
- if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) {
- if(v)
- goto bad;
- *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
- return;
- }
-
- scale = a->scale;
- if(t < D_INDIR || t >= 2*D_INDIR) {
- switch(a->type) {
- default:
- goto bad;
- case D_STATIC:
- case D_EXTERN:
- t = D_NONE;
- v = vaddr(a, &rel);
- break;
- case D_AUTO:
- case D_PARAM:
- t = D_SP;
- break;
- }
- scale = 1;
- } else
- t -= D_INDIR;
-
- if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
- *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
- goto putrelv;
- }
- if(t == D_SP) {
- if(v == 0 && rel.siz == 0) {
- *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
- asmidx(scale, D_NONE, t);
- return;
- }
- if(v >= -128 && v < 128 && rel.siz == 0) {
- *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
- asmidx(scale, D_NONE, t);
- *andptr++ = v;
- return;
- }
- *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
- asmidx(scale, D_NONE, t);
- goto putrelv;
- }
- if(t >= D_AX && t <= D_DI) {
- if(v == 0 && rel.siz == 0 && t != D_BP) {
- *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
- return;
- }
- if(v >= -128 && v < 128 && rel.siz == 0 && a->index != D_FS && a->index != D_GS) {
- andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
- andptr[1] = v;
- andptr += 2;
- return;
- }
- *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
- goto putrelv;
- }
- goto bad;
-
-putrelv:
- if(rel.siz != 0) {
- Reloc *r;
-
- if(rel.siz != 4) {
- diag("bad rel");
- goto bad;
- }
- r = addrel(cursym);
- *r = rel;
- r->off = curp->pc + andptr - and;
- } else if(iself && linkmode == LinkExternal && istls(a) && HEADTYPE != Hopenbsd) {
- Reloc *r;
- Sym *s;
-
- r = addrel(cursym);
- r->off = curp->pc + andptr - and;
- r->add = a->offset-tlsoffset;
- r->xadd = r->add;
- r->siz = 4;
- r->type = D_TLS;
- s = lookup("runtime.tlsgm", 0);
- r->sym = s;
- r->xsym = s;
- v = 0;
- }
-
- put4(v);
- return;
-
-bad:
- diag("asmand: bad address %D", a);
- return;
-}
-
-#define E 0xff
-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,
- 0
-};
-
-// byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
-// which is not referenced in a->type.
-// If a is empty, it returns BX to account for MULB-like instructions
-// that might use DX and AX.
-int
-byteswapreg(Adr *a)
-{
- int cana, canb, canc, cand;
-
- cana = canb = canc = cand = 1;
-
- switch(a->type) {
- case D_NONE:
- cana = cand = 0;
- break;
- case D_AX:
- case D_AL:
- case D_AH:
- case D_INDIR+D_AX:
- cana = 0;
- break;
- case D_BX:
- case D_BL:
- case D_BH:
- case D_INDIR+D_BX:
- canb = 0;
- break;
- case D_CX:
- case D_CL:
- case D_CH:
- case D_INDIR+D_CX:
- canc = 0;
- break;
- case D_DX:
- case D_DL:
- case D_DH:
- case D_INDIR+D_DX:
- cand = 0;
- break;
- }
- switch(a->index) {
- case D_AX:
- cana = 0;
- break;
- case D_BX:
- canb = 0;
- break;
- case D_CX:
- canc = 0;
- break;
- case D_DX:
- cand = 0;
- break;
- }
- if(cana)
- return D_AX;
- if(canb)
- return D_BX;
- if(canc)
- return D_CX;
- if(cand)
- return D_DX;
-
- diag("impossible byte register");
- errorexit();
- return 0;
-}
-
-void
-subreg(Prog *p, int from, int to)
-{
-
- if(debug['Q'])
- print("\n%P s/%R/%R/\n", p, from, to);
-
- if(p->from.type == from) {
- p->from.type = to;
- p->ft = 0;
- }
- if(p->to.type == from) {
- p->to.type = 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;
- }
-
- from += D_INDIR;
- if(p->from.type == from) {
- p->from.type = to+D_INDIR;
- p->ft = 0;
- }
- if(p->to.type == from) {
- p->to.type = to+D_INDIR;
- p->tt = 0;
- }
-
- if(debug['Q'])
- print("%P\n", p);
-}
-
-static int
-mediaop(Optab *o, int op, int osize, int z)
-{
- switch(op){
- case Pm:
- case Pe:
- case Pf2:
- case Pf3:
- if(osize != 1){
- if(op != Pm)
- *andptr++ = op;
- *andptr++ = Pm;
- op = o->op[++z];
- break;
- }
- default:
- if(andptr == and || andptr[-1] != Pm)
- *andptr++ = Pm;
- break;
- }
- *andptr++ = op;
- return z;
-}
-
-void
-doasm(Prog *p)
-{
- Optab *o;
- Prog *q, pp;
- uchar *t;
- int z, op, ft, tt, breg;
- int32 v, pre;
- Reloc rel, *r;
- Adr *a;
-
- curp = p; // TODO
-
- pre = prefixof(&p->from);
- if(pre)
- *andptr++ = pre;
- pre = prefixof(&p->to);
- if(pre)
- *andptr++ = pre;
-
- if(p->ft == 0)
- p->ft = oclass(&p->from);
- if(p->tt == 0)
- p->tt = oclass(&p->to);
-
- ft = p->ft * Ymax;
- tt = p->tt * Ymax;
- o = &optab[p->as];
- t = o->ytab;
- if(t == 0) {
- 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 */
- *andptr++ = Pe;
- *andptr++ = Pm;
- break;
-
- case Pf2: /* xmm opcode escape */
- case Pf3:
- *andptr++ = o->prefix;
- *andptr++ = Pm;
- break;
-
- case Pm: /* opcode escape */
- *andptr++ = Pm;
- break;
-
- case Pe: /* 16 bit escape */
- *andptr++ = Pe;
- break;
-
- case Pb: /* botch */
- break;
- }
-
- op = o->op[z];
- switch(t[2]) {
- default:
- diag("asmins: unknown z %d %P", t[2], p);
- return;
-
- case Zpseudo:
- break;
-
- case Zlit:
- for(; op = o->op[z]; z++)
- *andptr++ = op;
- break;
-
- case Zlitm_r:
- for(; op = o->op[z]; z++)
- *andptr++ = op;
- asmand(&p->from, reg[p->to.type]);
- break;
-
- case Zm_r:
- *andptr++ = op;
- asmand(&p->from, reg[p->to.type]);
- break;
-
- case Zm2_r:
- *andptr++ = op;
- *andptr++ = o->op[z+1];
- asmand(&p->from, reg[p->to.type]);
- break;
-
- case Zm_r_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->from, reg[p->to.type]);
- break;
-
- case Zm_r_i_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->from, reg[p->to.type]);
- *andptr++ = p->to.offset;
- break;
-
- case Zibm_r:
- while ((op = o->op[z++]) != 0)
- *andptr++ = op;
- asmand(&p->from, reg[p->to.type]);
- *andptr++ = p->to.offset;
- break;
-
- case Zaut_r:
- *andptr++ = 0x8d; /* leal */
- if(p->from.type != D_ADDR)
- diag("asmins: Zaut sb type ADDR");
- p->from.type = p->from.index;
- p->from.index = D_NONE;
- p->ft = 0;
- asmand(&p->from, reg[p->to.type]);
- p->from.index = p->from.type;
- p->from.type = D_ADDR;
- p->ft = 0;
- break;
-
- case Zm_o:
- *andptr++ = op;
- asmand(&p->from, o->op[z+1]);
- break;
-
- case Zr_m:
- *andptr++ = op;
- asmand(&p->to, reg[p->from.type]);
- break;
-
- case Zr_m_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->to, reg[p->from.type]);
- break;
-
- case Zr_m_i_xm:
- mediaop(o, op, t[3], z);
- asmand(&p->to, reg[p->from.type]);
- *andptr++ = p->from.offset;
- break;
-
- case Zo_m:
- *andptr++ = op;
- asmand(&p->to, o->op[z+1]);
- break;
-
- case Zm_ibo:
- *andptr++ = op;
- asmand(&p->from, o->op[z+1]);
- *andptr++ = vaddr(&p->to, nil);
- break;
-
- case Zibo_m:
- *andptr++ = op;
- asmand(&p->to, o->op[z+1]);
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Z_ib:
- case Zib_:
- if(t[2] == Zib_)
- a = &p->from;
- else
- a = &p->to;
- v = vaddr(a, nil);
- *andptr++ = op;
- *andptr++ = v;
- break;
-
- case Zib_rp:
- *andptr++ = op + reg[p->to.type];
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Zil_rp:
- *andptr++ = op + reg[p->to.type];
- if(o->prefix == Pe) {
- v = vaddr(&p->from, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, &p->from);
- break;
-
- case Zib_rr:
- *andptr++ = op;
- asmand(&p->to, reg[p->to.type]);
- *andptr++ = vaddr(&p->from, nil);
- break;
-
- case Z_il:
- case Zil_:
- if(t[2] == Zil_)
- a = &p->from;
- else
- a = &p->to;
- *andptr++ = op;
- if(o->prefix == Pe) {
- v = vaddr(a, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, a);
- break;
-
- case Zm_ilo:
- case Zilo_m:
- *andptr++ = op;
- if(t[2] == Zilo_m) {
- a = &p->from;
- asmand(&p->to, o->op[z+1]);
- } else {
- a = &p->to;
- asmand(&p->from, o->op[z+1]);
- }
- if(o->prefix == Pe) {
- v = vaddr(a, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, a);
- break;
-
- case Zil_rr:
- *andptr++ = op;
- asmand(&p->to, reg[p->to.type]);
- if(o->prefix == Pe) {
- v = vaddr(&p->from, nil);
- *andptr++ = v;
- *andptr++ = v>>8;
- }
- else
- relput4(p, &p->from);
- break;
-
- case Z_rp:
- *andptr++ = op + reg[p->to.type];
- break;
-
- case Zrp_:
- *andptr++ = op + reg[p->from.type];
- break;
-
- case Zclr:
- *andptr++ = op;
- asmand(&p->to, reg[p->to.type]);
- break;
-
- case Zcall:
- q = p->pcond;
- if(q == nil) {
- diag("call without target");
- errorexit();
- }
- if(q->as != ATEXT) {
- // Could handle this case by making D_PCREL
- // record the Prog* instead of the Sym*, but let's
- // wait until the need arises.
- diag("call of non-TEXT %P", q);
- errorexit();
- }
- *andptr++ = op;
- r = addrel(cursym);
- r->off = p->pc + andptr - and;
- r->type = D_PCREL;
- r->siz = 4;
- r->sym = q->from.sym;
- put4(0);
- break;
-
- case Zbr:
- case Zjmp:
- case Zloop:
- q = p->pcond;
- if(q == nil) {
- diag("jmp/branch/loop without target");
- errorexit();
- }
- if(q->as == ATEXT) {
- // jump out of function
- if(t[2] == Zbr) {
- diag("branch to ATEXT");
- errorexit();
- }
- *andptr++ = o->op[z+1];
- r = addrel(cursym);
- r->off = p->pc + andptr - and;
- r->sym = q->from.sym;
- r->type = D_PCREL;
- r->siz = 4;
- put4(0);
- break;
- }
-
- // Assumes q is in this function.
- // TODO: Check in input, preserve in brchain.
-
- // Fill in backward jump now.
- if(p->back & 1) {
- v = q->pc - (p->pc + 2);
- if(v >= -128) {
- if(p->as == AJCXZW)
- *andptr++ = 0x67;
- *andptr++ = op;
- *andptr++ = v;
- } else if(t[2] == Zloop) {
- diag("loop too far: %P", p);
- } else {
- v -= 5-2;
- if(t[2] == Zbr) {
- *andptr++ = 0x0f;
- v--;
- }
- *andptr++ = o->op[z+1];
- *andptr++ = v;
- *andptr++ = v>>8;
- *andptr++ = v>>16;
- *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)
- *andptr++ = 0x67;
- *andptr++ = op;
- *andptr++ = 0;
- } else if(t[2] == Zloop) {
- diag("loop too far: %P", p);
- } else {
- if(t[2] == Zbr)
- *andptr++ = 0x0f;
- *andptr++ = o->op[z+1];
- *andptr++ = 0;
- *andptr++ = 0;
- *andptr++ = 0;
- *andptr++ = 0;
- }
- break;
-
- case Zcallcon:
- case Zjmpcon:
- if(t[2] == Zcallcon)
- *andptr++ = op;
- else
- *andptr++ = o->op[z+1];
- r = addrel(cursym);
- r->off = p->pc + andptr - and;
- r->type = D_PCREL;
- r->siz = 4;
- r->add = p->to.offset;
- put4(0);
- break;
-
- case Zcallind:
- *andptr++ = op;
- *andptr++ = o->op[z+1];
- r = addrel(cursym);
- r->off = p->pc + andptr - and;
- r->type = D_ADDR;
- r->siz = 4;
- r->add = p->to.offset;
- r->sym = p->to.sym;
- put4(0);
- break;
-
- case Zbyte:
- v = vaddr(&p->from, &rel);
- if(rel.siz != 0) {
- rel.siz = op;
- r = addrel(cursym);
- *r = rel;
- r->off = p->pc + andptr - and;
- }
- *andptr++ = v;
- if(op > 1) {
- *andptr++ = v>>8;
- if(op > 2) {
- *andptr++ = v>>16;
- *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.type;
- if(z >= D_BP && z <= D_DI) {
- if((breg = byteswapreg(&p->to)) != D_AX) {
- *andptr++ = 0x87; /* xchg lhs,bx */
- asmand(&p->from, reg[breg]);
- subreg(&pp, z, breg);
- doasm(&pp);
- *andptr++ = 0x87; /* xchg lhs,bx */
- asmand(&p->from, reg[breg]);
- } else {
- *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
- subreg(&pp, z, D_AX);
- doasm(&pp);
- *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
- }
- return;
- }
- z = p->to.type;
- if(z >= D_BP && z <= D_DI) {
- if((breg = byteswapreg(&p->from)) != D_AX) {
- *andptr++ = 0x87; /* xchg rhs,bx */
- asmand(&p->to, reg[breg]);
- subreg(&pp, z, breg);
- doasm(&pp);
- *andptr++ = 0x87; /* xchg rhs,bx */
- asmand(&p->to, reg[breg]);
- } else {
- *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
- subreg(&pp, z, D_AX);
- doasm(&pp);
- *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
- }
- return;
- }
- diag("doasm: notfound t2=%ux from=%ux to=%ux %P", t[2], p->from.type, p->to.type, p);
- return;
-
-mfound:
- switch(t[3]) {
- default:
- diag("asmins: unknown mov %d %P", t[3], p);
- break;
-
- case 0: /* lit */
- for(z=4; t[z]!=E; z++)
- *andptr++ = t[z];
- break;
-
- case 1: /* r,m */
- *andptr++ = t[4];
- asmand(&p->to, t[5]);
- break;
-
- case 2: /* m,r */
- *andptr++ = t[4];
- asmand(&p->from, t[5]);
- break;
-
- case 3: /* r,m - 2op */
- *andptr++ = t[4];
- *andptr++ = t[5];
- asmand(&p->to, t[6]);
- break;
-
- case 4: /* m,r - 2op */
- *andptr++ = t[4];
- *andptr++ = t[5];
- asmand(&p->from, t[6]);
- break;
-
- case 5: /* load full pointer, trash heap */
- if(t[4])
- *andptr++ = t[4];
- switch(p->to.index) {
- default:
- goto bad;
- case D_DS:
- *andptr++ = 0xc5;
- break;
- case D_SS:
- *andptr++ = 0x0f;
- *andptr++ = 0xb2;
- break;
- case D_ES:
- *andptr++ = 0xc4;
- break;
- case D_FS:
- *andptr++ = 0x0f;
- *andptr++ = 0xb4;
- break;
- case D_GS:
- *andptr++ = 0x0f;
- *andptr++ = 0xb5;
- break;
- }
- asmand(&p->from, reg[p->to.type]);
- break;
-
- case 6: /* double shift */
- z = p->from.type;
- switch(z) {
- default:
- goto bad;
- case D_CONST:
- *andptr++ = 0x0f;
- *andptr++ = t[4];
- asmand(&p->to, reg[p->from.index]);
- *andptr++ = p->from.offset;
- break;
- case D_CL:
- case D_CX:
- *andptr++ = 0x0f;
- *andptr++ = t[5];
- asmand(&p->to, reg[p->from.index]);
- break;
- }
- break;
-
- case 7: /* imul rm,r */
- if(t[4] == Pq) {
- *andptr++ = Pe;
- *andptr++ = Pm;
- } else
- *andptr++ = t[4];
- *andptr++ = t[5];
- asmand(&p->from, reg[p->to.type]);
- break;
- }
-}
-
-void
-asmins(Prog *p)
-{
- andptr = and;
- doasm(p);
- if(andptr > and+sizeof and) {
- print("and[] is too short - %ld byte instruction\n", andptr - and);
- errorexit();
- }
-}
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go
new file mode 100644
index 000000000..b278d08ce
--- /dev/null
+++ b/src/cmd/addr2line/addr2line_test.go
@@ -0,0 +1,115 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+)
+
+func loadSyms(t *testing.T) map[string]string {
+ cmd := exec.Command("go", "tool", "nm", os.Args[0])
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ syms := make(map[string]string)
+ scanner := bufio.NewScanner(bytes.NewReader(out))
+ for scanner.Scan() {
+ f := strings.Fields(scanner.Text())
+ if len(f) < 3 {
+ continue
+ }
+ syms[f[2]] = f[0]
+ }
+ if err := scanner.Err(); err != nil {
+ t.Fatalf("error reading symbols: %v", err)
+ }
+ return syms
+}
+
+func runAddr2Line(t *testing.T, exepath, addr string) (funcname, path, lineno string) {
+ cmd := exec.Command(exepath, os.Args[0])
+ cmd.Stdin = strings.NewReader(addr)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool addr2line %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ f := strings.Split(string(out), "\n")
+ if len(f) < 3 && f[2] == "" {
+ t.Fatal("addr2line output must have 2 lines")
+ }
+ funcname = f[0]
+ pathAndLineNo := f[1]
+ f = strings.Split(pathAndLineNo, ":")
+ if runtime.GOOS == "windows" {
+ switch len(f) {
+ case 2:
+ return funcname, f[0], f[1]
+ case 3:
+ return funcname, f[0] + ":" + f[1], f[2]
+ default:
+ t.Fatalf("no line number found in %q", pathAndLineNo)
+ }
+ }
+ if len(f) != 2 {
+ t.Fatalf("no line number found in %q", pathAndLineNo)
+ }
+ return funcname, f[0], f[1]
+}
+
+const symName = "cmd/addr2line.TestAddr2Line"
+
+func testAddr2Line(t *testing.T, exepath, addr string) {
+ funcName, srcPath, srcLineNo := runAddr2Line(t, exepath, addr)
+ if symName != funcName {
+ t.Fatalf("expected function name %v; got %v", symName, funcName)
+ }
+ fi1, err := os.Stat("addr2line_test.go")
+ if err != nil {
+ t.Fatalf("Stat failed: %v", err)
+ }
+ fi2, err := os.Stat(srcPath)
+ if err != nil {
+ t.Fatalf("Stat failed: %v", err)
+ }
+ if !os.SameFile(fi1, fi2) {
+ t.Fatalf("addr2line_test.go and %s are not same file", srcPath)
+ }
+ if srcLineNo != "94" {
+ t.Fatalf("line number = %v; want 94", srcLineNo)
+ }
+}
+
+// This is line 93. The test depends on that.
+func TestAddr2Line(t *testing.T) {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ syms := loadSyms(t)
+
+ tmpDir, err := ioutil.TempDir("", "TestAddr2Line")
+ if err != nil {
+ t.Fatal("TempDir failed: ", err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ exepath := filepath.Join(tmpDir, "testaddr2line.exe")
+ out, err := exec.Command("go", "build", "-o", exepath, "cmd/addr2line").CombinedOutput()
+ if err != nil {
+ t.Fatalf("go build -o %v cmd/addr2line: %v\n%s", exepath, err, string(out))
+ }
+
+ testAddr2Line(t, exepath, syms[symName])
+ testAddr2Line(t, exepath, "0x"+syms[symName])
+}
diff --git a/src/cmd/addr2line/main.c b/src/cmd/addr2line/main.c
deleted file mode 100644
index 54c4d90b5..000000000
--- a/src/cmd/addr2line/main.c
+++ /dev/null
@@ -1,90 +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.
-
-/*
- * addr2line simulation - only enough to make pprof work on Macs
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-void
-printusage(int fd)
-{
- fprint(fd, "usage: addr2line binary\n");
- fprint(fd, "reads addresses from standard input and writes two lines for each:\n");
- fprint(fd, "\tfunction name\n");
- fprint(fd, "\tfile:line\n");
-}
-
-void
-usage(void)
-{
- printusage(2);
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- int fd;
- char *p, *q;
- uvlong pc;
- Symbol s;
- Fhdr fhdr;
- Biobuf bin, bout;
- char file[1024];
-
- if(argc > 1 && strcmp(argv[1], "--help") == 0) {
- printusage(1);
- exits(0);
- }
-
- ARGBEGIN{
- default:
- usage();
- }ARGEND
-
- if(argc != 1)
- usage();
-
- fd = open(argv[0], OREAD);
- if(fd < 0)
- sysfatal("open %s: %r", argv[0]);
- if(crackhdr(fd, &fhdr) <= 0)
- sysfatal("crackhdr: %r");
- machbytype(fhdr.type);
- if(syminit(fd, &fhdr) <= 0)
- sysfatal("syminit: %r");
-
- Binit(&bin, 0, OREAD);
- Binit(&bout, 1, OWRITE);
- for(;;) {
- p = Brdline(&bin, '\n');
- if(p == nil)
- break;
- p[Blinelen(&bin)-1] = '\0';
- q = strchr(p, ':');
- if(q != nil) {
- // reverse: translate file:line to pc
- *q++ = '\0';
- pc = file2pc(p, atoi(q));
- if(pc == ~(uvlong)0)
- Bprint(&bout, "!%r\n");
- else
- Bprint(&bout, "0x%llux\n", pc);
- continue;
- }
- pc = strtoull(p, 0, 16);
- if(!findsym(pc, CTEXT, &s))
- s.name = "??";
- if(!fileline(file, sizeof file, pc))
- strcpy(file, "??:0");
- Bprint(&bout, "%s\n%s\n", s.name, file);
- }
- Bflush(&bout);
- exits(0);
-}
diff --git a/src/cmd/addr2line/main.go b/src/cmd/addr2line/main.go
new file mode 100644
index 000000000..b94ba12ef
--- /dev/null
+++ b/src/cmd/addr2line/main.go
@@ -0,0 +1,253 @@
+// 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.
+
+// Addr2line is a minimal simulation of the GNU addr2line tool,
+// just enough to support pprof.
+//
+// Usage:
+// go tool addr2line binary
+//
+// Addr2line reads hexadecimal addresses, one per line and with optional 0x prefix,
+// from standard input. For each input address, addr2line prints two output lines,
+// first the name of the function containing the address and second the file:line
+// of the source code corresponding to that address.
+//
+// This tool is intended for use only by pprof; its interface may change or
+// it may be deleted entirely in future releases.
+package main
+
+import (
+ "bufio"
+ "debug/elf"
+ "debug/gosym"
+ "debug/macho"
+ "debug/pe"
+ "debug/plan9obj"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func printUsage(w *os.File) {
+ fmt.Fprintf(w, "usage: addr2line binary\n")
+ fmt.Fprintf(w, "reads addresses from standard input and writes two lines for each:\n")
+ fmt.Fprintf(w, "\tfunction name\n")
+ fmt.Fprintf(w, "\tfile:line\n")
+}
+
+func usage() {
+ printUsage(os.Stderr)
+ os.Exit(2)
+}
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("addr2line: ")
+
+ // pprof expects this behavior when checking for addr2line
+ if len(os.Args) > 1 && os.Args[1] == "--help" {
+ printUsage(os.Stdout)
+ os.Exit(0)
+ }
+
+ flag.Usage = usage
+ flag.Parse()
+ if flag.NArg() != 1 {
+ usage()
+ }
+
+ f, err := os.Open(flag.Arg(0))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ textStart, symtab, pclntab, err := loadTables(f)
+ if err != nil {
+ log.Fatalf("reading %s: %v", flag.Arg(0), err)
+ }
+
+ pcln := gosym.NewLineTable(pclntab, textStart)
+ tab, err := gosym.NewTable(symtab, pcln)
+ if err != nil {
+ log.Fatalf("reading %s: %v", flag.Arg(0), err)
+ }
+
+ stdin := bufio.NewScanner(os.Stdin)
+ stdout := bufio.NewWriter(os.Stdout)
+
+ for stdin.Scan() {
+ p := stdin.Text()
+ if strings.Contains(p, ":") {
+ // Reverse translate file:line to pc.
+ // This was an extension in the old C version of 'go tool addr2line'
+ // and is probably not used by anyone, but recognize the syntax.
+ // We don't have an implementation.
+ fmt.Fprintf(stdout, "!reverse translation not implemented\n")
+ continue
+ }
+ pc, _ := strconv.ParseUint(strings.TrimPrefix(p, "0x"), 16, 64)
+ file, line, fn := tab.PCToLine(pc)
+ name := "?"
+ if fn != nil {
+ name = fn.Name
+ } else {
+ file = "?"
+ line = 0
+ }
+ fmt.Fprintf(stdout, "%s\n%s:%d\n", name, file, line)
+ }
+ stdout.Flush()
+}
+
+func loadTables(f *os.File) (textStart uint64, symtab, pclntab []byte, err error) {
+ if obj, err := elf.NewFile(f); err == nil {
+ if sect := obj.Section(".text"); sect != nil {
+ textStart = sect.Addr
+ }
+ if sect := obj.Section(".gosymtab"); sect != nil {
+ if symtab, err = sect.Data(); err != nil {
+ return 0, nil, nil, err
+ }
+ }
+ if sect := obj.Section(".gopclntab"); sect != nil {
+ if pclntab, err = sect.Data(); err != nil {
+ return 0, nil, nil, err
+ }
+ }
+ return textStart, symtab, pclntab, nil
+ }
+
+ if obj, err := macho.NewFile(f); err == nil {
+ if sect := obj.Section("__text"); sect != nil {
+ textStart = sect.Addr
+ }
+ if sect := obj.Section("__gosymtab"); sect != nil {
+ if symtab, err = sect.Data(); err != nil {
+ return 0, nil, nil, err
+ }
+ }
+ if sect := obj.Section("__gopclntab"); sect != nil {
+ if pclntab, err = sect.Data(); err != nil {
+ return 0, nil, nil, err
+ }
+ }
+ return textStart, symtab, pclntab, nil
+ }
+
+ if obj, err := pe.NewFile(f); err == nil {
+ var imageBase uint64
+ switch oh := obj.OptionalHeader.(type) {
+ case *pe.OptionalHeader32:
+ imageBase = uint64(oh.ImageBase)
+ case *pe.OptionalHeader64:
+ imageBase = oh.ImageBase
+ default:
+ return 0, nil, nil, fmt.Errorf("pe file format not recognized")
+ }
+ if sect := obj.Section(".text"); sect != nil {
+ textStart = imageBase + uint64(sect.VirtualAddress)
+ }
+ if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
+ return 0, nil, nil, err
+ }
+ if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil {
+ return 0, nil, nil, err
+ }
+ return textStart, symtab, pclntab, nil
+ }
+
+ if obj, err := plan9obj.NewFile(f); err == nil {
+ sym, err := findPlan9Symbol(obj, "text")
+ if err != nil {
+ return 0, nil, nil, err
+ }
+ textStart = sym.Value
+ if pclntab, err = loadPlan9Table(obj, "pclntab", "epclntab"); err != nil {
+ return 0, nil, nil, err
+ }
+ if symtab, err = loadPlan9Table(obj, "symtab", "esymtab"); err != nil {
+ return 0, nil, nil, err
+ }
+ return textStart, symtab, pclntab, nil
+ }
+
+ return 0, nil, nil, fmt.Errorf("unrecognized binary format")
+}
+
+func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
+ for _, s := range f.Symbols {
+ if s.Name != name {
+ continue
+ }
+ if s.SectionNumber <= 0 {
+ return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
+ }
+ if len(f.Sections) < int(s.SectionNumber) {
+ return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
+ }
+ return s, nil
+ }
+ return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
+ ssym, err := findPESymbol(f, sname)
+ if err != nil {
+ return nil, err
+ }
+ esym, err := findPESymbol(f, ename)
+ if err != nil {
+ return nil, err
+ }
+ if ssym.SectionNumber != esym.SectionNumber {
+ return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
+ }
+ sect := f.Sections[ssym.SectionNumber-1]
+ data, err := sect.Data()
+ if err != nil {
+ return nil, err
+ }
+ return data[ssym.Value:esym.Value], nil
+}
+
+func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
+ syms, err := f.Symbols()
+ if err != nil {
+ return nil, err
+ }
+ for _, s := range syms {
+ if s.Name != name {
+ continue
+ }
+ return &s, nil
+ }
+ return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
+ ssym, err := findPlan9Symbol(f, sname)
+ if err != nil {
+ return nil, err
+ }
+ esym, err := findPlan9Symbol(f, ename)
+ if err != nil {
+ return nil, err
+ }
+ text, err := findPlan9Symbol(f, "text")
+ if err != nil {
+ return nil, err
+ }
+ sect := f.Section("text")
+ if sect == nil {
+ return nil, err
+ }
+ data, err := sect.Data()
+ if err != nil {
+ return nil, err
+ }
+ return data[ssym.Value-text.Value : esym.Value-text.Value], nil
+}
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index a62c87421..4bde794a1 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -817,7 +817,7 @@ func (w *Walker) emitFunc(f *types.Func) {
func (w *Walker) emitMethod(m *types.Selection) {
sig := m.Type().(*types.Signature)
recv := sig.Recv().Type()
- // report exported methods with unexported reveiver base type
+ // report exported methods with unexported receiver base type
if true {
base := recv
if p, _ := recv.(*types.Pointer); p != nil {
diff --git a/src/cmd/api/run.go b/src/cmd/api/run.go
index 1e10dc600..896b2b4a1 100644
--- a/src/cmd/api/run.go
+++ b/src/cmd/api/run.go
@@ -46,14 +46,14 @@ func main() {
gopath := prepGoPath()
cmd := exec.Command("go", "install", "--tags=api_tool", "cmd/api")
- cmd.Env = append([]string{"GOPATH=" + gopath}, filterOut(os.Environ(), "GOARCH")...)
+ cmd.Env = append(filterOut(os.Environ(), "GOARCH", "GOPATH"), "GOPATH="+gopath)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("Error installing cmd/api: %v\n%s", err, out)
}
out, err = exec.Command("go", "tool", "api",
- "-c", file("go1", "go1.1", "go1.2"),
+ "-c", file("go1", "go1.1", "go1.2", "go1.3"),
"-next", file("next"),
"-except", file("except")).CombinedOutput()
if err != nil {
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index af2339c97..c8aac1253 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -30,6 +30,7 @@
#include <libc.h>
#include <bio.h>
+#include <link.h>
#ifndef EXTERN
#define EXTERN extern
@@ -48,13 +49,13 @@ typedef struct Type Type;
typedef struct Funct Funct;
typedef struct Decl Decl;
typedef struct Io Io;
-typedef struct Hist Hist;
typedef struct Term Term;
typedef struct Init Init;
typedef struct Bits Bits;
typedef struct Bvec Bvec;
typedef struct Dynimp Dynimp;
typedef struct Dynexp Dynexp;
+typedef struct Var Var;
typedef Rune TRune; /* target system type */
@@ -83,6 +84,14 @@ struct Bvec
uint32 b[];
};
+struct Var
+{
+ vlong offset;
+ LSym* sym;
+ char name;
+ char etype;
+};
+
struct Node
{
Node* left;
@@ -114,6 +123,7 @@ struct Node
struct Sym
{
Sym* link;
+ LSym* lsym;
Type* type;
Type* suetag;
Type* tenum;
@@ -200,16 +210,6 @@ struct Io
};
#define I ((Io*)0)
-struct Hist
-{
- Hist* link;
- char* name;
- int32 line;
- int32 offset;
-};
-#define H ((Hist*)0)
-EXTERN Hist* hist;
-
struct Term
{
vlong mult;
@@ -469,7 +469,6 @@ EXTERN int32 autoffset;
EXTERN int blockno;
EXTERN Decl* dclstack;
EXTERN int debug[256];
-EXTERN Hist* ehist;
EXTERN int32 firstbit;
EXTERN Sym* firstarg;
EXTERN Type* firstargtype;
@@ -498,7 +497,6 @@ EXTERN int32 nsymb;
EXTERN Biobuf outbuf;
EXTERN Biobuf diagbuf;
EXTERN char* outfile;
-EXTERN char* pathname;
EXTERN int peekc;
EXTERN int32 stkoff;
EXTERN Type* strf;
@@ -508,8 +506,9 @@ EXTERN Sym* symstring;
EXTERN int taggen;
EXTERN Type* tfield;
EXTERN Type* tufield;
-EXTERN int thechar;
-EXTERN char* thestring;
+extern int thechar;
+extern char* thestring;
+extern LinkArch* thelinkarch;
EXTERN Type* thisfn;
EXTERN int32 thunk;
EXTERN Type* types[NALLTYPES];
@@ -525,8 +524,11 @@ EXTERN int flag_largemodel;
EXTERN int ncontin;
EXTERN int canreach;
EXTERN int warnreach;
+EXTERN int nacl;
EXTERN Bits zbits;
EXTERN Fmt pragcgobuf;
+EXTERN Biobuf bstdout;
+EXTERN Var var[NVAR];
extern char *onames[], *tnames[], *gnames[];
extern char *cnames[], *qnames[], *bnames[];
@@ -556,6 +558,7 @@ extern uchar typechlpfd[];
EXTERN uchar* typeword;
EXTERN uchar* typecmplx;
+EXTERN Link* ctxt;
extern uint32 thash1;
extern uint32 thash2;
@@ -603,6 +606,7 @@ int FNconv(Fmt*);
int Oconv(Fmt*);
int Qconv(Fmt*);
int VBconv(Fmt*);
+int Bconv(Fmt*);
void setinclude(char*);
/*
@@ -612,7 +616,6 @@ void dodefine(char*);
void domacro(void);
Sym* getsym(void);
int32 getnsn(void);
-void linehist(char*, int);
void macdef(void);
void macprag(void);
void macend(void);
@@ -731,6 +734,7 @@ void diag(Node*, char*, ...);
void warn(Node*, char*, ...);
void yyerror(char*, ...);
void fatal(Node*, char*, ...);
+LSym* linksym(Sym*);
/*
* acid.c
@@ -791,6 +795,7 @@ int32 exreg(Type*);
int32 align(int32, Type*, int, int32*);
int32 maxround(int32, int32);
int hasdotdotdot(void);
+void linkarchinit(void);
extern schar ewidth[];
@@ -814,6 +819,7 @@ int machcap(Node*);
#pragma varargck argpos diag 2
#pragma varargck argpos yyerror 1
+#pragma varargck type "B" Bits
#pragma varargck type "F" Node*
#pragma varargck type "L" int32
#pragma varargck type "Q" int32
diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c
index 049dc5196..424843764 100644
--- a/src/cmd/cc/lex.c
+++ b/src/cmd/cc/lex.c
@@ -117,8 +117,28 @@ void
main(int argc, char *argv[])
{
int c;
+ char *p;
+
+ // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+ // but not other values.
+ p = getgoarch();
+ if(strncmp(p, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
+ if(strcmp(p, "amd64p32") == 0) // must be before cinit
+ ewidth[TIND] = 4;
+
+ nacl = strcmp(getgoos(), "nacl") == 0;
+ if(nacl)
+ flag_largemodel = 1;
quotefmtinstall(); // before cinit, which overrides %Q
+
+ linkarchinit();
+ ctxt = linknew(thelinkarch);
+ ctxt->diag = yyerror;
+ ctxt->bso = &bstdout;
+ Binit(&bstdout, 1, OWRITE);
+
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
tinit();
@@ -175,12 +195,14 @@ main(int argc, char *argv[])
flagcount("q", "print Go definitions", &debug['q']);
flagcount("s", "print #define assembly offsets", &debug['s']);
flagcount("t", "debug code generation", &debug['t']);
+ flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
flagcount("w", "enable warnings", &debug['w']);
flagcount("v", "increase debug verbosity", &debug['v']);
if(thechar == '6')
flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
flagparse(&argc, &argv, usage);
+ ctxt->debugasm = debug['S'];
if(argc < 1 && outfile == 0)
usage();
@@ -195,6 +217,7 @@ main(int argc, char *argv[])
else
c = compile(argv[0], defs, ndef);
+ Bflush(&bstdout);
if(c)
errorexit();
exits(0);
@@ -331,6 +354,7 @@ compile(char *file, char **defs, int ndef)
void
errorexit(void)
{
+ Bflush(&bstdout);
if(outfile)
remove(outfile);
exits("error");
@@ -390,7 +414,7 @@ newfile(char *s, int f)
errorexit();
}
fi.c = 0;
- linehist(s, 0);
+ linklinehist(ctxt, lineno, s, 0);
}
Sym*
@@ -1300,13 +1324,6 @@ cinit(void)
nodproto = new(OPROTO, Z, Z);
dclstack = D;
- pathname = allocn(pathname, 0, 100);
- if(getwd(pathname, 99) == 0) {
- pathname = allocn(pathname, 100, 900);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
- }
-
fmtinstall('O', Oconv);
fmtinstall('T', Tconv);
fmtinstall('F', FNconv);
@@ -1314,6 +1331,7 @@ cinit(void)
fmtinstall('Q', Qconv);
fmtinstall('|', VBconv);
fmtinstall('U', Uconv);
+ fmtinstall('B', Bconv);
}
int
@@ -1330,7 +1348,7 @@ loop:
fi.c = read(i->f, i->b, BUFSIZ) - 1;
if(fi.c < 0) {
close(i->f);
- linehist(0, 0);
+ linklinehist(ctxt, lineno, nil, 0);
goto pop;
}
fi.p = i->b + 1;
@@ -1365,70 +1383,7 @@ Oconv(Fmt *fp)
int
Lconv(Fmt *fp)
{
- char str[STRINGSZ], s[STRINGSZ];
- Hist *h;
- 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 l, d;
- int i, n;
-
- l = va_arg(fp->args, int32);
- n = 0;
- for(h = hist; h != H; h = h->link) {
- if(l < h->line)
- break;
- if(h->name) {
- if(h->offset != 0) { /* #line directive, not #pragma */
- if(n > 0 && n < HISTSZ && h->offset >= 0) {
- a[n-1].line = h;
- a[n-1].ldel = h->line - h->offset + 1;
- }
- } else {
- if(n < HISTSZ) { /* beginning of file */
- 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;
- str[0] = 0;
- for(i=n-1; i>=0; i--) {
- if(i != n-1) {
- if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */
- break;
- strcat(str, " ");
- }
- if(a[i].line)
- snprint(s, STRINGSZ, "%s:%d[%s:%d]",
- a[i].line->name, l-a[i].ldel+1,
- a[i].incl->name, l-a[i].idel+1);
- else
- snprint(s, STRINGSZ, "%s:%d",
- a[i].incl->name, l-a[i].idel+1);
- if(strlen(s)+strlen(str) >= STRINGSZ-10)
- break;
- strcat(str, s);
- l = a[i].incl->line - 1; /* now print out start of this file */
- }
- if(n == 0)
- strcat(str, "<eof>");
- return fmtstrcpy(fp, str);
+ return linklinefmt(ctxt, fp);
}
int
@@ -1548,6 +1503,32 @@ VBconv(Fmt *fp)
return fmtstrcpy(fp, str);
}
+int
+Bconv(Fmt *fp)
+{
+ char str[STRINGSZ], ss[STRINGSZ], *s;
+ Bits bits;
+ int i;
+
+ str[0] = 0;
+ bits = va_arg(fp->args, Bits);
+ while(bany(&bits)) {
+ i = bnum(bits);
+ if(str[0])
+ strcat(str, " ");
+ if(var[i].sym == nil) {
+ sprint(ss, "$%lld", var[i].offset);
+ s = ss;
+ } else
+ s = var[i].sym->name;
+ if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
+ break;
+ strcat(str, s);
+ bits.b[i/32] &= ~(1L << (i%32));
+ }
+ return fmtstrcpy(fp, str);
+}
+
void
setinclude(char *p)
{
diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody
index 9d293b089..e24db1bc0 100644
--- a/src/cmd/cc/lexbody
+++ b/src/cmd/cc/lexbody
@@ -152,7 +152,7 @@ setinclude(char *p)
void
errorexit(void)
{
-
+ Bflush(&bstdout);
if(outfile)
remove(outfile);
exits("error");
@@ -209,7 +209,7 @@ newfile(char *s, int f)
errorexit();
}
fi.c = 0;
- linehist(s, 0);
+ linklinehist(ctxt, lineno, s, 0);
}
Sym*
@@ -477,7 +477,7 @@ l1:
return LCONST;
case '"':
- memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));
+ memcpy(yylval.sval, nullgen.u.sval, sizeof(yylval.sval));
cp = yylval.sval;
c1 = 0;
for(;;) {
@@ -638,10 +638,6 @@ pinit(char *f)
pc = 0;
peekc = IGN;
sym = 1;
- for(i=0; i<NSYM; i++) {
- h[i].type = 0;
- h[i].sym = S;
- }
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link)
s->macro = 0;
@@ -661,7 +657,7 @@ loop:
fi.c = read(i->f, i->b, BUFSIZ) - 1;
if(fi.c < 0) {
close(i->f);
- linehist(0, 0);
+ linklinehist(ctxt, lineno, 0, 0);
goto pop;
}
fi.p = i->b + 1;
@@ -709,67 +705,5 @@ yyerror(char *a, ...)
void
prfile(int32 l)
{
- int i, n;
- Hist a[HISTSZ], *h;
- int32 d;
-
- n = 0;
- for(h = hist; h != H; 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));
-}
-
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldn't use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l = (uint32)ieee->l << 16;
- ieee->l |= (int32)(fr*f);
+ linkprfile(ctxt, l);
}
diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody
index f0a507669..f6927b2f6 100644
--- a/src/cmd/cc/macbody
+++ b/src/cmd/cc/macbody
@@ -642,7 +642,7 @@ nn:
c = strlen(symb) + 1;
cp = alloc(c);
memcpy(cp, symb, c);
- linehist(cp, n);
+ linklinehist(ctxt, lineno, cp, n);
return;
bad:
@@ -713,7 +713,6 @@ macprag(void)
Sym *s;
int c0, c;
char *hp;
- Hist *h;
s = getsym();
@@ -779,18 +778,7 @@ praglib:
hp = alloc(c);
memcpy(hp, symb, c);
- h = alloc(sizeof(Hist));
- h->name = hp;
- h->line = lineno;
- h->offset = -1;
- h->link = H;
- if(ehist == H) {
- hist = h;
- ehist = h;
- return;
- }
- ehist->link = h;
- ehist = h;
+ linklinehist(ctxt, lineno, hp, -1);
return;
bad:
@@ -810,43 +798,3 @@ macend(void)
return;
}
}
-
-void
-linehist(char *f, int offset)
-{
- Hist *h;
-
- /*
- * overwrite the last #line directive if
- * no alloc has happened since the last one
- */
- if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0)
- if(f && ehist->name && strcmp(f, ehist->name) == 0) {
- ehist->line = lineno;
- ehist->offset = offset;
- return;
- }
-
- if(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);
- newflag = 0;
-
- h = alloc(sizeof(Hist));
- h->name = f;
- h->line = lineno;
- h->offset = offset;
- h->link = H;
- if(ehist == H) {
- hist = h;
- ehist = h;
- return;
- }
- ehist->link = h;
- ehist = h;
-}
diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c
index b82872bc5..10bebc196 100644
--- a/src/cmd/cc/pgen.c
+++ b/src/cmd/cc/pgen.c
@@ -35,6 +35,26 @@ enum { BitsPerPointer = 2 };
static void dumpgcargs(Type *fn, Sym *sym);
+static Sym*
+makefuncdatasym(char *namefmt, int64 funcdatakind)
+{
+ Node nod;
+ Sym *sym;
+ static int32 nsym;
+ static char namebuf[40];
+
+ snprint(namebuf, sizeof(namebuf), namefmt, nsym++);
+ sym = slookup(namebuf);
+ sym->class = CSTATIC;
+ memset(&nod, 0, sizeof nod);
+ nod.op = ONAME;
+ nod.sym = sym;
+ nod.class = CSTATIC;
+ gins(AFUNCDATA, nodconst(funcdatakind), &nod);
+ linksym(sym)->type = SRODATA;
+ return sym;
+}
+
int
hasdotdotdot(void)
{
@@ -80,10 +100,10 @@ void
codgen(Node *n, Node *nn)
{
Prog *sp;
- Node *n1, nod, nod1, nod2;
- Sym *gcsym, *gclocalssym;
- static int ngcsym, ngclocalssym;
- static char namebuf[40];
+ Node *n1, nod, nod1;
+ Sym *gcargs;
+ Sym *gclocals;
+ int isvarargs;
cursafe = 0;
curarg = 0;
@@ -109,25 +129,11 @@ codgen(Node *n, Node *nn)
* generate funcdata symbol for this function.
* data is filled in at the end of codgen().
*/
- snprint(namebuf, sizeof namebuf, "gc·%d", ngcsym++);
- gcsym = slookup(namebuf);
- gcsym->class = CSTATIC;
-
- memset(&nod, 0, sizeof nod);
- nod.op = ONAME;
- nod.sym = gcsym;
- nod.class = CSTATIC;
- gins(AFUNCDATA, nodconst(FUNCDATA_GCArgs), &nod);
-
- snprint(namebuf, sizeof(namebuf), "gclocalssym·%d", ngclocalssym++);
- gclocalssym = slookup(namebuf);
- gclocalssym->class = CSTATIC;
-
- memset(&nod2, 0, sizeof(nod2));
- nod2.op = ONAME;
- nod2.sym = gclocalssym;
- nod2.class = CSTATIC;
- gins(AFUNCDATA, nodconst(FUNCDATA_GCLocals), &nod2);
+ isvarargs = hasdotdotdot();
+ gcargs = nil;
+ if(!isvarargs)
+ gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps);
+ gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
/*
* isolate first argument
@@ -166,7 +172,8 @@ codgen(Node *n, Node *nn)
maxargsafe = xround(maxargsafe, 8);
sp->to.offset += maxargsafe;
- dumpgcargs(thisfn, gcsym);
+ if(!isvarargs)
+ dumpgcargs(thisfn, gcargs);
// TODO(rsc): "stkoff" is not right. It does not account for
// the possibility of data stored in .safe variables.
@@ -177,9 +184,9 @@ codgen(Node *n, Node *nn)
// area its own section.
// That said, we've been using stkoff for months
// and nothing too terrible has happened.
- gextern(gclocalssym, nodconst(-stkoff), 0, 4); // locals
- gclocalssym->type = typ(0, T);
- gclocalssym->type->width = 4;
+ gextern(gclocals, nodconst(-stkoff), 0, 4); // locals
+ gclocals->type = typ(0, T);
+ gclocals->type->width = 4;
}
void
@@ -655,7 +662,9 @@ walktype1(Type *t, int32 offset, Bvec *bv, int param)
{
Type *t1;
int32 o;
+ int32 widthptr;
+ widthptr = ewidth[TIND];
switch(t->etype) {
case TCHAR:
case TUCHAR:
@@ -670,14 +679,16 @@ walktype1(Type *t, int32 offset, Bvec *bv, int param)
case TFLOAT:
case TDOUBLE:
// non-pointer types
+ for(o = 0; o < t->width; o++)
+ bvset(bv, ((offset + t->offset + o) / widthptr) * BitsPerPointer); // 1 = live scalar
break;
case TIND:
pointer:
// pointer types
- if((offset + t->offset) % ewidth[TIND] != 0)
+ if((offset + t->offset) % widthptr != 0)
yyerror("unaligned pointer");
- bvset(bv, ((offset + t->offset) / ewidth[TIND])*BitsPerPointer);
+ bvset(bv, ((offset + t->offset) / widthptr)*BitsPerPointer + 1); // 2 = live ptr
break;
case TARRAY:
@@ -715,39 +726,39 @@ dumpgcargs(Type *fn, Sym *sym)
int32 argbytes;
int32 symoffset, argoffset;
- if(hasdotdotdot()) {
- // give up for C vararg functions.
- // TODO: maybe make a map just for the args we do know?
- gextern(sym, nodconst(0), 0, 4); // nptrs=0
- symoffset = 4;
- } else {
- argbytes = (argsize() + ewidth[TIND] - 1);
- bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer);
- argoffset = align(0, fn->link, Aarg0, nil);
- if(argoffset > 0) {
- // The C calling convention returns structs by
- // copying them to a location pointed to by a
- // hidden first argument. This first argument
- // is a pointer.
- if(argoffset != ewidth[TIND])
- yyerror("passbyptr arg not the right size");
- bvset(bv, 0);
- }
- for(t = fn->down; t != T; t = t->down) {
- if(t->etype == TVOID)
- continue;
- argoffset = align(argoffset, t, Aarg1, nil);
- walktype1(t, argoffset, bv, 1);
- argoffset = align(argoffset, t, Aarg2, nil);
- }
- gextern(sym, nodconst(bv->n), 0, 4);
- symoffset = 4;
- for(i = 0; i < bv->n; i += 32) {
- gextern(sym, nodconst(bv->b[i/32]), symoffset, 4);
- symoffset += 4;
- }
- free(bv);
+ // Dump the length of the bitmap array. This value is always one for
+ // functions written in C.
+ symoffset = 0;
+ gextern(sym, nodconst(1), symoffset, 4);
+ symoffset += 4;
+ argbytes = (argsize() + ewidth[TIND] - 1);
+ bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer);
+ argoffset = align(0, fn->link, Aarg0, nil);
+ if(argoffset > 0) {
+ // The C calling convention returns structs by copying them to a
+ // location pointed to by a hidden first argument. This first
+ // argument is a pointer.
+ if(argoffset != ewidth[TIND])
+ yyerror("passbyptr arg not the right size");
+ bvset(bv, 1); // 2 = live ptr
+ }
+ for(t = fn->down; t != T; t = t->down) {
+ if(t->etype == TVOID)
+ continue;
+ argoffset = align(argoffset, t, Aarg1, nil);
+ walktype1(t, argoffset, bv, 1);
+ argoffset = align(argoffset, t, Aarg2, nil);
+ }
+ // Dump the length of the bitmap.
+ gextern(sym, nodconst(bv->n), symoffset, 4);
+ symoffset += 4;
+ // Dump the words of the bitmap.
+ for(i = 0; i < bv->n; i += 32) {
+ gextern(sym, nodconst(bv->b[i/32]), symoffset, 4);
+ symoffset += 4;
}
+ free(bv);
+ // Finalize the gc symbol.
sym->type = typ(0, T);
sym->type->width = symoffset;
}
diff --git a/src/cmd/cc/pswt.c b/src/cmd/cc/pswt.c
index cc9c22763..bae57c64d 100644
--- a/src/cmd/cc/pswt.c
+++ b/src/cmd/cc/pswt.c
@@ -138,32 +138,3 @@ nullwarn(Node *l, Node *r)
if(r != Z)
cgen(r, Z);
}
-
-void
-ieeedtod(Ieee *ieee, double native)
-{
- double fr, ho, f;
- int exp;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldn't use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l <<= 16;
- ieee->l |= (int32)(fr*f);
-}
diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c
index bed989102..94c11d021 100644
--- a/src/cmd/cc/sub.c
+++ b/src/cmd/cc/sub.c
@@ -2056,3 +2056,13 @@ mixedasop(Type *l, Type *r)
{
return !typefd[l->etype] && typefd[r->etype];
}
+
+LSym*
+linksym(Sym *s)
+{
+ if(s == nil)
+ return nil;
+ if(s->lsym != nil)
+ return s->lsym;
+ return linklookup(ctxt, s->name, s->class == CSTATIC);
+}
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 605bab6d2..69c7ce893 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -52,6 +52,14 @@ these directives. Package-specific flags should be set using the
directives, not the environment variables, so that builds work in
unmodified environments.
+All the cgo CPPFLAGS and CFLAGS directives in a package are concatenated and
+used to compile C files in that package. All the CPPFLAGS and CXXFLAGS
+directives in a package are concatenated and used to compile C++ files in that
+package. All the LDFLAGS directives in any package in the program are
+concatenated and used at link time. All the pkg-config directives are
+concatenated and sent to pkg-config simultaneously to add to each appropriate
+set of command-line flags.
+
When the Go tool sees that one or more Go files use the special import
"C", it will look for other non-Go files in the directory and compile
them as part of the Go package. Any .c, .s, or .S files will be
@@ -63,11 +71,26 @@ compilers may be changed by the CC and CXX environment variables,
respectively; those environment variables may include command line
options.
+To enable cgo during cross compiling builds, set the CGO_ENABLED
+environment variable to 1 when building the Go tools with make.bash.
+Also, set CC_FOR_TARGET to the C cross compiler for the target. CC will
+be used for compiling for the host.
+
+After the Go tools are built, when running the go command, CC_FOR_TARGET is
+ignored. The value of CC_FOR_TARGET when running make.bash is the default
+compiler. However, you can set the environment variable CC, not CC_FOR_TARGET,
+to control the compiler when running the go tool.
+
+CXX_FOR_TARGET works in a similar way for C++ code.
+
Go references to C
Within the Go file, C's struct field names that are keywords in Go
can be accessed by prefixing them with an underscore: if x points at a C
struct with a field named "type", x._type accesses the field.
+C struct fields that cannot be expressed in Go, such as bit fields
+or misaligned data, are omitted in the Go struct, replaced by
+appropriate padding to reach the next field or the end of the struct.
The standard C numeric types are available under the names
C.char, C.schar (signed char), C.uchar (unsigned char),
@@ -84,6 +107,11 @@ C's union types are represented as a Go byte array with the same length.
Go structs cannot embed fields with C types.
+Cgo translates C types into equivalent unexported Go types.
+Because the translations are unexported, a Go package should not
+expose C types in its exported API: a C type used in one Go package
+is different from the same C type used in another.
+
Any C function (even void functions) may be called in a multiple
assignment context to retrieve both the return value (if any) and the
C errno variable as an error (use _ to skip the result value if the
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index 3e1837ebf..7a802102d 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -1197,12 +1197,12 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
return t
case *dwarf.StructType:
- if dt.ByteSize < 0 { // opaque struct
- break
- }
// Convert to Go struct, being careful about alignment.
// Have to give it a name to simulate C "struct foo" references.
tag := dt.StructName
+ if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
+ break
+ }
if tag == "" {
tag = "__" + strconv.Itoa(tagGen)
tagGen++
@@ -1212,6 +1212,16 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
t.Go = name // publish before recursive calls
goIdent[name.Name] = name
+ if dt.ByteSize < 0 {
+ // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
+ // so execute the basic things that the struct case would do
+ // other than try to determine a Go representation.
+ tt := *t
+ tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
+ tt.Go = c.Ident("struct{}")
+ typedef[name.Name] = &tt
+ break
+ }
switch dt.Kind {
case "class", "union":
t.Go = c.Opaque(t.Size)
@@ -1259,13 +1269,33 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
sub := c.Type(dt.Type, pos)
t.Size = sub.Size
t.Align = sub.Align
- if _, ok := typedef[name.Name]; !ok {
+ oldType := typedef[name.Name]
+ if oldType == nil {
tt := *t
tt.Go = sub.Go
typedef[name.Name] = &tt
}
- if *godefs || *cdefs {
+
+ // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
+ // use that as the Go form for this typedef too, so that the typedef will be interchangeable
+ // with the base type.
+ // In -godefs and -cdefs mode, do this for all typedefs.
+ if isStructUnionClass(sub.Go) || *godefs || *cdefs {
t.Go = sub.Go
+
+ if isStructUnionClass(sub.Go) {
+ // Use the typedef name for C code.
+ typedef[sub.Go.(*ast.Ident).Name].C = t.C
+ }
+
+ // If we've seen this typedef before, and it
+ // was an anonymous struct/union/class before
+ // too, use the old definition.
+ // TODO: it would be safer to only do this if
+ // we verify that the types are the same.
+ if oldType != nil && isStructUnionClass(oldType.Go) {
+ t.Go = oldType.Go
+ }
}
case *dwarf.UcharType:
@@ -1327,9 +1357,21 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
// be correct, so calling dtype.Size again will produce the correct value.
t.Size = dtype.Size()
if t.Size < 0 {
- // Unsized types are [0]byte
+ // Unsized types are [0]byte, unless they're typedefs of other types
+ // or structs with tags.
+ // if so, use the name we've already defined.
t.Size = 0
- t.Go = c.Opaque(0)
+ switch dt := dtype.(type) {
+ case *dwarf.TypedefType:
+ // ok
+ case *dwarf.StructType:
+ if dt.StructName != "" {
+ break
+ }
+ t.Go = c.Opaque(0)
+ default:
+ t.Go = c.Opaque(0)
+ }
if t.C.Empty() {
t.C.Set("void")
}
@@ -1344,6 +1386,19 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
return t
}
+// isStructUnionClass reports whether the type described by the Go syntax x
+// is a struct, union, or class with a tag.
+func isStructUnionClass(x ast.Expr) bool {
+ id, ok := x.(*ast.Ident)
+ if !ok {
+ return false
+ }
+ name := id.Name
+ return strings.HasPrefix(name, "_Ctype_struct_") ||
+ strings.HasPrefix(name, "_Ctype_union_") ||
+ strings.HasPrefix(name, "_Ctype_class_")
+}
+
// FuncArg returns a Go type with the same memory layout as
// dtype when used as the type of a C function argument.
func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
@@ -1496,7 +1551,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
t := c.Type(f.Type, pos)
tgo := t.Go
size := t.Size
-
+ talign := t.Align
if f.BitSize > 0 {
if f.BitSize%8 != 0 {
continue
@@ -1509,8 +1564,17 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
name = "uint"
}
tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
+ talign = size
}
+ if talign > 0 && f.ByteOffset%talign != 0 {
+ // Drop misaligned fields, the same way we drop integer bit fields.
+ // The goal is to make available what can be made available.
+ // Otherwise one bad and unneeded field in an otherwise okay struct
+ // makes the whole program not compile. Much of the time these
+ // structs are in system headers that cannot be corrected.
+ continue
+ }
n := len(fld)
fld = fld[0 : n+1]
name := f.Name
@@ -1525,8 +1589,8 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
buf.WriteString(" ")
buf.WriteString(name)
buf.WriteString("; ")
- if t.Align > align {
- align = t.Align
+ if talign > align {
+ align = talign
}
}
if off < dt.ByteSize {
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 83ab95251..76c7247af 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -485,7 +485,7 @@ func (p *Package) writeOutput(f *File, srcfile string) {
fgcc.Close()
}
-// fixGo convers the internal Name.Go field into the name we should show
+// fixGo converts the internal Name.Go field into the name we should show
// to users in error messages. There's only one for now: on input we rewrite
// C.malloc into C._CMalloc, so change it back here.
func fixGo(name string) string {
@@ -529,15 +529,8 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
}
// We're trying to write a gcc struct that matches 6c/8c/5c's layout.
// Use packed attribute to force no padding in this struct in case
- // gcc has different packing requirements. For example,
- // on 386 Windows, gcc wants to 8-align int64s, but 8c does not.
- // Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
- // and http://golang.org/issue/5603.
- extraAttr := ""
- if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" || goarch == "386") {
- extraAttr = ", __gcc_struct__"
- }
- fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__%v)) *a = v;\n", ctype, extraAttr)
+ // gcc has different packing requirements.
+ fmt.Fprintf(fgcc, "\t%s %v *a = v;\n", ctype, p.packedAttribute())
fmt.Fprintf(fgcc, "\t")
if t := n.FuncType.Result; t != nil {
fmt.Fprintf(fgcc, "a->r = ")
@@ -618,6 +611,19 @@ func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
fmt.Fprintf(fgcc, "\n")
}
+// packedAttribute returns host compiler struct attribute that will be
+// used to match 6c/8c/5c's struct layout. For example, on 386 Windows,
+// gcc wants to 8-align int64s, but 8c does not.
+// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
+// and http://golang.org/issue/5603.
+func (p *Package) packedAttribute() string {
+ s := "__attribute__((__packed__"
+ if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" || goarch == "386") {
+ s += ", __gcc_struct__"
+ }
+ return s + "))"
+}
+
// Write out the various stubs we need to support functions exported
// from Go so that they are callable from C.
func (p *Package) writeExports(fgo2, fc, fm *os.File) {
@@ -727,7 +733,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int);\n", cPrefix, exp.ExpName)
fmt.Fprintf(fgcc, "\n%s\n", s)
fmt.Fprintf(fgcc, "{\n")
- fmt.Fprintf(fgcc, "\t%s __attribute__((packed)) a;\n", ctype)
+ fmt.Fprintf(fgcc, "\t%s %v a;\n", ctype, p.packedAttribute())
if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
}
@@ -874,10 +880,24 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
fmt.Fprintf(cdeclBuf, ")")
cParams := cdeclBuf.String()
+ // We need to use a name that will be exported by the
+ // Go code; otherwise gccgo will make it static and we
+ // will not be able to link against it from the C
+ // code.
goName := "Cgoexp_" + exp.ExpName
fmt.Fprintf(fgcch, `extern %s %s %s __asm__("%s.%s");`, cRet, goName, cParams, gccgoSymbolPrefix, goName)
fmt.Fprint(fgcch, "\n")
+ // Use a #define so that the C code that includes
+ // cgo_export.h will be able to refer to the Go
+ // function using the expected name.
+ fmt.Fprintf(fgcch, "#define %s %s\n", exp.ExpName, goName)
+
+ // Use a #undef in _cgo_export.c so that we ignore the
+ // #define from cgo_export.h, since here we are
+ // defining the real function.
+ fmt.Fprintf(fgcc, "#undef %s\n", exp.ExpName)
+
fmt.Fprint(fgcc, "\n")
fmt.Fprintf(fgcc, "%s %s %s {\n", cRet, exp.ExpName, cParams)
fmt.Fprint(fgcc, "\t")
@@ -1219,7 +1239,10 @@ struct __go_string __go_byte_array_to_string(const void* p, intgo len);
struct __go_open_array __go_string_to_byte_array (struct __go_string str);
const char *_cgoPREFIX_Cfunc_CString(struct __go_string s) {
- return strndup((const char*)s.__data, s.__length);
+ char *p = malloc(s.__length+1);
+ memmove(p, s.__data, s.__length);
+ p[s.__length] = 0;
+ return p;
}
struct __go_string _cgoPREFIX_Cfunc_GoString(char *p) {
diff --git a/src/cmd/dist/a.h b/src/cmd/dist/a.h
index 9de93180f..6222e5060 100644
--- a/src/cmd/dist/a.h
+++ b/src/cmd/dist/a.h
@@ -75,7 +75,8 @@ extern char *goroot_final;
extern char *goextlinkenabled;
extern char *goversion;
extern char *defaultcc;
-extern char *defaultcxx;
+extern char *defaultcxxtarget;
+extern char *defaultcctarget;
extern char *workdir;
extern char *tooldir;
extern char *slash;
@@ -93,7 +94,7 @@ void cmdversion(int, char**);
// buildgc.c
void gcopnames(char*, char*);
-void mkenam(char*, char*);
+void mkanames(char*, char*);
// buildruntime.c
void mkzasm(char*, char*);
diff --git a/src/cmd/dist/arm.c b/src/cmd/dist/arm.c
index dafc5c1c2..52a621c5d 100644
--- a/src/cmd/dist/arm.c
+++ b/src/cmd/dist/arm.c
@@ -17,16 +17,8 @@ static void useVFPv1(void);
char *
xgetgoarm(void)
{
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- // NetBSD has buggy support for VFPv2 (incorrect inexact,
- // denormial, and NaN handling). When GOARM=6, some of our
- // math tests fails on Raspberry Pi.
- // Thus we return "5" here for safety, the user is free
- // to override.
- // Note: using GOARM=6 with cgo can trigger a kernel assertion
- // failure and crash NetBSD/evbarm kernel.
- // FreeBSD also have broken VFP support, so disable VFP also
- // on FreeBSD.
+#if defined(__FreeBSD__)
+ // FreeBSD has broken VFP support
return "5";
#endif
if(xtryexecfunc(useVFPv3))
diff --git a/src/cmd/dist/build.c b/src/cmd/dist/build.c
index e6e5f0cf7..6884e0aae 100644
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -27,22 +27,27 @@ char *gochar;
char *goversion;
char *slash; // / for unix, \ for windows
char *defaultcc;
-char *defaultcxx;
+char *defaultcflags;
+char *defaultldflags;
+char *defaultcxxtarget;
+char *defaultcctarget;
bool rebuildall;
bool defaultclang;
static bool shouldbuild(char*, char*);
static void copy(char*, char*, int);
+static void dopack(char*, char*, char**, int);
static char *findgoversion(void);
// The known architecture letters.
-static char *gochars = "568";
+static char *gochars = "5668";
// The known architectures.
static char *okgoarch[] = {
// same order as gochars
"arm",
"amd64",
+ "amd64p32",
"386",
};
@@ -51,7 +56,9 @@ static char *okgoos[] = {
"darwin",
"dragonfly",
"linux",
+ "solaris",
"freebsd",
+ "nacl",
"netbsd",
"openbsd",
"plan9",
@@ -164,14 +171,29 @@ init(void)
}
defaultcc = btake(&b);
- xgetenv(&b, "CXX");
+ xgetenv(&b, "CFLAGS");
+ defaultcflags = btake(&b);
+
+ xgetenv(&b, "LDFLAGS");
+ defaultldflags = btake(&b);
+
+ xgetenv(&b, "CC_FOR_TARGET");
if(b.len == 0) {
- if(defaultclang)
- bprintf(&b, "clang++");
- else
- bprintf(&b, "g++");
+ bprintf(&b, defaultcc);
}
- defaultcxx = btake(&b);
+ defaultcctarget = btake(&b);
+
+ xgetenv(&b, "CXX_FOR_TARGET");
+ if(b.len == 0) {
+ xgetenv(&b, "CXX");
+ if(b.len == 0) {
+ if(defaultclang)
+ bprintf(&b, "clang++");
+ else
+ bprintf(&b, "g++");
+ }
+ }
+ defaultcxxtarget = btake(&b);
xsetenv("GOROOT", goroot);
xsetenv("GOARCH", goarch);
@@ -268,9 +290,8 @@ findgoversion(void)
p = tags.p[i];
if(streq(p, "+"))
nrev++;
- // NOTE: Can reenable the /* */ code when we want to
- // start reporting versions named 'weekly' again.
- if(/*hasprefix(p, "weekly.") ||*/ hasprefix(p, "go")) {
+ // Only show the beta tag for the exact revision.
+ if(hasprefix(p, "go") && (!contains(p, "beta") || nrev == 0)) {
tag = xstrdup(p);
// If this tag matches the current checkout
// exactly (no "+" yet), don't show extra
@@ -344,7 +365,8 @@ static char *oldtool[] = {
// Unreleased directories (relative to $GOROOT) that should
// not be in release branches.
static char *unreleased[] = {
- "src/cmd/prof",
+ "src/cmd/link",
+ "src/pkg/debug/goobj",
"src/pkg/old",
};
@@ -414,7 +436,7 @@ setup(void)
}
// For release, make sure excluded things are excluded.
- if(hasprefix(goversion, "release.") || hasprefix(goversion, "go")) {
+ if(hasprefix(goversion, "release.") || (hasprefix(goversion, "go") && !contains(goversion, "beta"))) {
for(i=0; i<nelem(unreleased); i++)
if(isdir(bpathf(&b, "%s/%s", goroot, unreleased[i])))
fatal("%s should not exist in release build", bstr(&b));
@@ -435,7 +457,6 @@ static char *proto_gccargs[] = {
"-Wstrict-prototypes",
"-Wextra",
"-Wunused",
- "-Wuninitialized",
"-Wno-sign-compare",
"-Wno-missing-braces",
"-Wno-parentheses",
@@ -447,6 +468,15 @@ static char *proto_gccargs[] = {
"-fno-common",
"-ggdb",
"-pipe",
+};
+
+// gccargs2 is the second part of gccargs.
+// it is used if the environment isn't defining CFLAGS.
+static char *proto_gccargs2[] = {
+ // on older versions of GCC, -Wuninitialized is not supported
+ // without -O, so put it here together with -O settings in case
+ // the user's $CFLAGS doesn't include -O.
+ "-Wuninitialized",
#if defined(__NetBSD__) && defined(__arm__)
// GCC 4.5.4 (NetBSD nb1 20120916) on ARM is known to mis-optimize gc/mparith3.c
// Fix available at http://patchwork.ozlabs.org/patch/64562/.
@@ -456,7 +486,7 @@ static char *proto_gccargs[] = {
#endif
};
-static Vec gccargs;
+static Vec gccargs, ldargs;
// deptab lists changes to the default dependencies for a given prefix.
// deps ending in /* read the whole directory; deps beginning with -
@@ -480,18 +510,17 @@ static struct {
"$GOROOT/include/libc.h",
"$GOROOT/include/bio.h",
}},
- {"libmach", {
+ {"liblink", {
"$GOROOT/include/u.h",
"$GOROOT/include/utf.h",
"$GOROOT/include/fmt.h",
"$GOROOT/include/libc.h",
"$GOROOT/include/bio.h",
"$GOROOT/include/ar.h",
- "$GOROOT/include/bootexec.h",
- "$GOROOT/include/mach.h",
- "$GOROOT/include/ureg_amd64.h",
- "$GOROOT/include/ureg_arm.h",
- "$GOROOT/include/ureg_x86.h",
+ "$GOROOT/include/link.h",
+ "anames5.c",
+ "anames6.c",
+ "anames8.c",
}},
{"cmd/cc", {
"-pgen.c",
@@ -500,6 +529,7 @@ static struct {
{"cmd/gc", {
"-cplx.c",
"-pgen.c",
+ "-plive.c",
"-popt.c",
"-y1.tab.c", // makefile dreg
"opnames.h",
@@ -507,64 +537,58 @@ static struct {
{"cmd/5c", {
"../cc/pgen.c",
"../cc/pswt.c",
- "../5l/enam.c",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libcc.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
}},
{"cmd/6c", {
"../cc/pgen.c",
"../cc/pswt.c",
- "../6l/enam.c",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libcc.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
}},
{"cmd/8c", {
"../cc/pgen.c",
"../cc/pswt.c",
- "../8l/enam.c",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libcc.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
}},
{"cmd/5g", {
"../gc/cplx.c",
"../gc/pgen.c",
+ "../gc/plive.c",
"../gc/popt.c",
"../gc/popt.h",
- "../5l/enam.c",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libgc.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
}},
{"cmd/6g", {
"../gc/cplx.c",
"../gc/pgen.c",
+ "../gc/plive.c",
"../gc/popt.c",
"../gc/popt.h",
- "../6l/enam.c",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libgc.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
}},
{"cmd/8g", {
"../gc/cplx.c",
"../gc/pgen.c",
+ "../gc/plive.c",
"../gc/popt.c",
"../gc/popt.h",
- "../8l/enam.c",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libgc.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
}},
{"cmd/5l", {
"../ld/*",
- "enam.c",
}},
{"cmd/6l", {
"../ld/*",
- "enam.c",
}},
{"cmd/8l", {
"../ld/*",
- "enam.c",
}},
{"cmd/go", {
"zdefaultcc.go",
}},
{"cmd/", {
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libmach.a",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/libbio.a",
- "$GOROOT/pkg/obj/$GOOS_$GOARCH/lib9.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/liblink.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libbio.a",
+ "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/lib9.a",
}},
{"pkg/runtime", {
"zaexperiment.h", // must sort above zasm
@@ -592,7 +616,9 @@ static struct {
void (*gen)(char*, char*);
} gentab[] = {
{"opnames.h", gcopnames},
- {"enam.c", mkenam},
+ {"anames5.c", mkanames},
+ {"anames6.c", mkanames},
+ {"anames8.c", mkanames},
{"zasm_", mkzasm},
{"zdefaultcc.go", mkzdefaultcc},
{"zsys_", mkzsys},
@@ -601,6 +627,9 @@ static struct {
{"zruntime_defs_", mkzruntimedefs},
{"zversion.go", mkzversion},
{"zaexperiment.h", mkzexperiment},
+
+ // not generated anymore, but delete the file if we see it
+ {"enam.c", nil},
};
// install installs the library, package, or binary associated with dir,
@@ -609,11 +638,11 @@ static void
install(char *dir)
{
char *name, *p, *elem, *prefix, *exe;
- bool islib, ispkg, isgo, stale;
+ bool islib, ispkg, isgo, stale, ispackcmd;
Buf b, b1, path;
Vec compile, files, link, go, missing, clean, lib, extra;
Time ttarg, t;
- int i, j, k, n, doclean, targ, usecpp;
+ int i, j, k, n, doclean, targ;
if(vflag) {
if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
@@ -646,30 +675,33 @@ install(char *dir)
goto out;
}
- // For release, cmd/prof is not included.
- if((streq(dir, "cmd/prof")) && !isdir(bstr(&path))) {
- if(vflag > 1)
- errprintf("skipping %s - does not exist\n", dir);
- goto out;
- }
-
// set up gcc command line on first run.
if(gccargs.len == 0) {
- bprintf(&b, "%s", defaultcc);
+ bprintf(&b, "%s %s", defaultcc, defaultcflags);
splitfields(&gccargs, bstr(&b));
for(i=0; i<nelem(proto_gccargs); i++)
vadd(&gccargs, proto_gccargs[i]);
+ if(defaultcflags[0] == '\0') {
+ for(i=0; i<nelem(proto_gccargs2); i++)
+ vadd(&gccargs, proto_gccargs2[i]);
+ }
if(contains(gccargs.p[0], "clang")) {
// disable ASCII art in clang errors, if possible
vadd(&gccargs, "-fno-caret-diagnostics");
// clang is too smart about unused command-line arguments
vadd(&gccargs, "-Qunused-arguments");
}
+ // disable word wrapping in error messages
+ vadd(&gccargs, "-fmessage-length=0");
if(streq(gohostos, "darwin")) {
// golang.org/issue/5261
vadd(&gccargs, "-mmacosx-version-min=10.6");
}
}
+ if(ldargs.len == 0 && defaultldflags[0] != '\0') {
+ bprintf(&b, "%s", defaultldflags);
+ splitfields(&ldargs, bstr(&b));
+ }
islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc");
ispkg = hasprefix(dir, "pkg");
@@ -681,6 +713,7 @@ install(char *dir)
// Start final link command line.
// Note: code below knows that link.p[targ] is the target.
+ ispackcmd = 0;
if(islib) {
// C library.
vadd(&link, "ar");
@@ -695,8 +728,8 @@ install(char *dir)
vadd(&link, bpathf(&b, "%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name));
} else if(ispkg) {
// Go library (package).
- vadd(&link, bpathf(&b, "%s/pack", tooldir));
- vadd(&link, "grc");
+ ispackcmd = 1;
+ vadd(&link, "pack"); // program name - unused here, but all the other cases record one
p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir+4);
*xstrrchr(p, '/') = '\0';
xmkdirall(p);
@@ -712,7 +745,7 @@ install(char *dir)
targ = link.len;
vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe));
} else {
- // C command. Use gccargs.
+ // C command. Use gccargs and ldargs.
if(streq(gohostos, "plan9")) {
vadd(&link, bprintf(&b, "%sl", gohostchar));
vadd(&link, "-o");
@@ -720,6 +753,7 @@ install(char *dir)
vadd(&link, bpathf(&b, "%s/%s", tooldir, name));
} else {
vcopy(&link, gccargs.p, gccargs.len);
+ vcopy(&link, ldargs.p, ldargs.len);
if(sflag)
vadd(&link, "-static");
vadd(&link, "-o");
@@ -754,17 +788,18 @@ install(char *dir)
files.len = n;
for(i=0; i<nelem(deptab); i++) {
- if(hasprefix(dir, deptab[i].prefix)) {
+ if(streq(dir, deptab[i].prefix) ||
+ (hassuffix(deptab[i].prefix, "/") && hasprefix(dir, deptab[i].prefix))) {
for(j=0; (p=deptab[i].dep[j])!=nil; j++) {
breset(&b1);
bwritestr(&b1, p);
bsubst(&b1, "$GOROOT", goroot);
bsubst(&b1, "$GOOS", goos);
bsubst(&b1, "$GOARCH", goarch);
+ bsubst(&b1, "$GOHOSTOS", gohostos);
+ bsubst(&b1, "$GOHOSTARCH", gohostarch);
p = bstr(&b1);
if(hassuffix(p, ".a")) {
- if(streq(gohostos, "plan9") && hassuffix(p, "libbio.a"))
- continue;
vadd(&lib, bpathf(&b, "%s", p));
continue;
}
@@ -865,6 +900,8 @@ install(char *dir)
p = files.p[i];
elem = lastelem(p);
for(j=0; j<nelem(gentab); j++) {
+ if(gentab[j].gen == nil)
+ continue;
if(hasprefix(elem, gentab[j].nameprefix)) {
if(vflag > 1)
errprintf("generate %s\n", p);
@@ -916,20 +953,6 @@ install(char *dir)
goto nobuild;
}
- // The files generated by GNU Bison use macros that aren't
- // supported by the Plan 9 compilers so we have to use the
- // external preprocessor when compiling.
- usecpp = 0;
- if(streq(gohostos, "plan9")) {
- for(i=0; i<files.len; i++) {
- p = files.p[i];
- if(hassuffix(p, "y.tab.c") || hassuffix(p, "y.tab.h")){
- usecpp = 1;
- break;
- }
- }
- }
-
// Compile the files.
for(i=0; i<files.len; i++) {
if(!hassuffix(files.p[i], ".c") && !hassuffix(files.p[i], ".s"))
@@ -941,13 +964,12 @@ install(char *dir)
// C library or tool.
if(streq(gohostos, "plan9")) {
vadd(&compile, bprintf(&b, "%sc", gohostchar));
- vadd(&compile, "-FTVw");
- if(usecpp)
- vadd(&compile, "-Bp+");
+ vadd(&compile, "-FTVwp");
+ vadd(&compile, "-DPLAN9");
+ vadd(&compile, "-D__STDC__=1");
+ vadd(&compile, "-D__SIZE_TYPE__=ulong"); // for GNU Bison
vadd(&compile, bpathf(&b, "-I%s/include/plan9", goroot));
vadd(&compile, bpathf(&b, "-I%s/include/plan9/%s", goroot, gohostarch));
- // Work around Plan 9 C compiler's handling of #include with .. path.
- vadd(&compile, bpathf(&b, "-I%s/src/cmd/ld", goroot));
} else {
vcopy(&compile, gccargs.p, gccargs.len);
vadd(&compile, "-c");
@@ -955,13 +977,15 @@ install(char *dir)
vadd(&compile, "-m64");
else if(streq(gohostarch, "386"))
vadd(&compile, "-m32");
- if(streq(dir, "lib9"))
- vadd(&compile, "-DPLAN9PORT");
vadd(&compile, "-I");
vadd(&compile, bpathf(&b, "%s/include", goroot));
}
+ if(streq(dir, "lib9"))
+ vadd(&compile, "-DPLAN9PORT");
+
+
vadd(&compile, "-I");
vadd(&compile, bstr(&path));
@@ -1048,11 +1072,13 @@ install(char *dir)
vreset(&compile);
vadd(&compile, bpathf(&b, "%s/%sg", tooldir, gochar));
- bpathf(&b, "%s/_go_.%s", workdir, gochar);
+ bpathf(&b, "%s/_go_.a", workdir);
+ vadd(&compile, "-pack");
vadd(&compile, "-o");
vadd(&compile, bstr(&b));
vadd(&clean, bstr(&b));
- vadd(&link, bstr(&b));
+ if(!ispackcmd)
+ vadd(&link, bstr(&b));
vadd(&compile, "-p");
if(hasprefix(dir, "pkg/"))
@@ -1066,6 +1092,12 @@ install(char *dir)
vcopy(&compile, go.p, go.len);
runv(nil, bstr(&path), CheckExit, &compile);
+
+ if(ispackcmd) {
+ xremove(link.p[targ]);
+ dopack(link.p[targ], bstr(&b), &link.p[targ+1], link.len - (targ+1));
+ goto nobuild;
+ }
}
if(!islib && !isgo) {
@@ -1138,21 +1170,6 @@ shouldbuild(char *file, char *dir)
int i, j, ret;
Buf b;
Vec lines, fields;
-
- // On Plan 9, most of the libraries are already present.
- // The main exception is libmach which has been modified
- // in various places to support Go object files.
- if(streq(gohostos, "plan9")) {
- if(streq(dir, "lib9")) {
- name = lastelem(file);
- if(streq(name, "goos.c") || streq(name, "flag.c"))
- return 1;
- if(!contains(name, "plan9"))
- return 0;
- }
- if(streq(dir, "libbio"))
- return 0;
- }
// Check file name for GOOS or GOARCH.
name = lastelem(file);
@@ -1238,20 +1255,56 @@ copy(char *dst, char *src, int exec)
bfree(&b);
}
+// dopack copies the package src to dst,
+// appending the files listed in extra.
+// The archive format is the traditional Unix ar format.
+static void
+dopack(char *dst, char *src, char **extra, int nextra)
+{
+ int i;
+ char c, *p, *q;
+ Buf b, bdst;
+
+ binit(&b);
+ binit(&bdst);
+
+ readfile(&bdst, src);
+ for(i=0; i<nextra; i++) {
+ readfile(&b, extra[i]);
+ // find last path element for archive member name
+ p = xstrrchr(extra[i], '/');
+ if(p)
+ p++;
+ q = xstrrchr(extra[i], '\\');
+ if(q) {
+ q++;
+ if(p == nil || q > p)
+ p = q;
+ }
+ if(p == nil)
+ p = extra[i];
+ bwritef(&bdst, "%-16.16s%-12d%-6d%-6d%-8o%-10d`\n", p, 0, 0, 0, 0644, b.len);
+ bwriteb(&bdst, &b);
+ if(b.len&1) {
+ c = 0;
+ bwrite(&bdst, &c, 1);
+ }
+ }
+
+ writefile(&bdst, dst, 0);
+
+ bfree(&b);
+ bfree(&bdst);
+}
+
// buildorder records the order of builds for the 'go bootstrap' command.
static char *buildorder[] = {
"lib9",
"libbio",
- "libmach",
+ "liblink",
"misc/pprof",
- "cmd/addr2line",
- "cmd/nm",
- "cmd/objdump",
- "cmd/pack",
- "cmd/prof",
-
"cmd/cc", // must be before c
"cmd/gc", // must be before g
"cmd/%sl", // must be before a, c, g
@@ -1323,17 +1376,12 @@ static char *cleantab[] = {
"cmd/8c",
"cmd/8g",
"cmd/8l",
- "cmd/addr2line",
"cmd/cc",
"cmd/gc",
- "cmd/go",
- "cmd/nm",
- "cmd/objdump",
- "cmd/pack",
- "cmd/prof",
+ "cmd/go",
"lib9",
"libbio",
- "libmach",
+ "liblink",
"pkg/bufio",
"pkg/bytes",
"pkg/container/heap",
@@ -1388,8 +1436,6 @@ clean(void)
vinit(&dir);
for(i=0; i<nelem(cleantab); i++) {
- if((streq(cleantab[i], "cmd/prof")) && !isdir(cleantab[i]))
- continue;
bpathf(&path, "%s/src/%s", goroot, cleantab[i]);
xreaddir(&dir, bstr(&path));
// Remove generated files.
@@ -1488,6 +1534,7 @@ cmdenv(int argc, char **argv)
usage();
xprintf(format, "CC", defaultcc);
+ xprintf(format, "CC_FOR_TARGET", defaultcctarget);
xprintf(format, "GOROOT", goroot);
xprintf(format, "GOBIN", gobin);
xprintf(format, "GOARCH", goarch);
diff --git a/src/cmd/dist/buildgc.c b/src/cmd/dist/buildgc.c
index 03a797f2c..1f0625daa 100644
--- a/src/cmd/dist/buildgc.c
+++ b/src/cmd/dist/buildgc.c
@@ -63,10 +63,10 @@ gcopnames(char *dir, char *file)
vfree(&fields);
}
-// mkenam reads [568].out.h and writes enam.c
+// mkanames reads [568].out.h and writes anames[568].c
// The format is much the same as the Go opcodes above.
void
-mkenam(char *dir, char *file)
+mkanames(char *dir, char *file)
{
int i, ch;
Buf in, b, out;
@@ -78,11 +78,11 @@ mkenam(char *dir, char *file)
binit(&out);
vinit(&lines);
- ch = dir[xstrlen(dir)-2];
- bprintf(&b, "%s/../%cl/%c.out.h", dir, ch, ch);
+ ch = file[xstrlen(file)-3];
+ bprintf(&b, "%s/../cmd/%cl/%c.out.h", dir, ch, ch);
readfile(&in, bstr(&b));
splitlines(&lines, bstr(&in));
- bwritestr(&out, "char* anames[] = {\n");
+ bprintf(&out, "char* anames%c[] = {\n", ch);
for(i=0; i<lines.len; i++) {
if(hasprefix(lines.p[i], "\tA")) {
p = xstrstr(lines.p[i], ",");
diff --git a/src/cmd/dist/buildgo.c b/src/cmd/dist/buildgo.c
index a340252bc..41208fac5 100644
--- a/src/cmd/dist/buildgo.c
+++ b/src/cmd/dist/buildgo.c
@@ -31,7 +31,7 @@ mkzdefaultcc(char *dir, char *file)
"\n"
"const defaultCC = `%s`\n"
"const defaultCXX = `%s`\n",
- defaultcc, defaultcxx);
+ defaultcctarget, defaultcxxtarget);
writefile(&out, file, 0);
diff --git a/src/cmd/dist/buildruntime.c b/src/cmd/dist/buildruntime.c
index e6e309d92..ba5993b2f 100644
--- a/src/cmd/dist/buildruntime.c
+++ b/src/cmd/dist/buildruntime.c
@@ -127,83 +127,22 @@ static struct {
char *goos;
char *hdr;
} zasmhdr[] = {
- {"386", "windows",
- "#define get_tls(r) MOVL 0x14(FS), r\n"
- "#define g(r) 0(r)\n"
- "#define m(r) 4(r)\n"
- },
- {"386", "plan9",
- "// Plan 9 does not have per-process segment descriptors with\n"
- "// which to do thread-local storage. Instead, we will use a\n"
- "// fixed offset from the per-process TOS struct address for\n"
- "// the local storage. Since the process ID is contained in the\n"
- "// TOS struct, we specify an offset for that here as well.\n"
- "#define get_tls(r) MOVL _tos(SB), r \n"
- "#define g(r) -8(r)\n"
- "#define m(r) -4(r)\n"
- "#define procid(r) 48(r)\n"
- },
- {"386", "linux",
- "// On Linux systems, what we call 0(GS) and 4(GS) for g and m\n"
- "// turn into %gs:-8 and %gs:-4 (using gcc syntax to denote\n"
- "// what the machine sees as opposed to 8l input).\n"
- "// 8l rewrites 0(GS) and 4(GS) into these.\n"
- "//\n"
- "// On Linux Xen, it is not allowed to use %gs:-8 and %gs:-4\n"
- "// directly. Instead, we have to store %gs:0 into a temporary\n"
- "// register and then use -8(%reg) and -4(%reg). This kind\n"
- "// of addressing is correct even when not running Xen.\n"
- "//\n"
- "// 8l can rewrite MOVL 0(GS), CX into the appropriate pair\n"
- "// of mov instructions, using CX as the intermediate register\n"
- "// (safe because CX is about to be written to anyway).\n"
- "// But 8l cannot handle other instructions, like storing into 0(GS),\n"
- "// which is where these macros come into play.\n"
- "// get_tls sets up the temporary and then g and r use it.\n"
- "//\n"
- "// Another wrinkle is that get_tls needs to read from %gs:0,\n"
- "// but in 8l input it's called 8(GS), because 8l is going to\n"
- "// subtract 8 from all the offsets, as described above.\n"
- "//\n"
- "// The final wrinkle is that when generating an ELF .o file for\n"
- "// external linking mode, we need to be able to relocate the\n"
- "// -8(r) and -4(r) instructions. Tag them with an extra (GS*1)\n"
- "// that is ignored by the linker except for that identification.\n"
- "#define get_tls(r) MOVL 8(GS), r\n"
- "#define g(r) -8(r)(GS*1)\n"
- "#define m(r) -4(r)(GS*1)\n"
- },
{"386", "",
- "#define get_tls(r)\n"
- "#define g(r) 0(GS)\n"
- "#define m(r) 4(GS)\n"
- },
-
- {"amd64", "windows",
- "#define get_tls(r) MOVQ 0x28(GS), r\n"
- "#define g(r) 0(r)\n"
- "#define m(r) 8(r)\n"
+ "#define get_tls(r) MOVL TLS, r\n"
+ "#define g(r) 0(r)(TLS*1)\n"
+ "#define m(r) 4(r)(TLS*1)\n"
},
- {"amd64", "plan9",
- "#define get_tls(r)\n"
- "#define g(r) 0(GS)\n"
- "#define m(r) 8(GS)\n"
- "#define procid(r) 16(GS)\n"
- },
- // The TLS accessors here are defined here to use initial exec model.
- // If the linker is not outputting a shared library, it will reduce
- // the TLS accessors to the local exec model, effectively removing
- // get_tls().
- {"amd64", "linux",
- "#define get_tls(r) MOVQ runtime·tlsgm(SB), r\n"
- "#define g(r) 0(r)(GS*1)\n"
- "#define m(r) 8(r)(GS*1)\n"
+ {"amd64p32", "",
+ "#define get_tls(r) MOVL TLS, r\n"
+ "#define g(r) 0(r)(TLS*1)\n"
+ "#define m(r) 4(r)(TLS*1)\n"
},
{"amd64", "",
- "#define get_tls(r)\n"
- "#define g(r) 0(GS)\n"
- "#define m(r) 8(GS)\n"
+ "#define get_tls(r) MOVQ TLS, r\n"
+ "#define g(r) 0(r)(TLS*1)\n"
+ "#define m(r) 8(r)(TLS*1)\n"
},
+
{"arm", "",
"#define LR R14\n"
},
@@ -243,7 +182,8 @@ mkzasm(char *dir, char *file)
ok:
// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -a -n -o workdir/proc.acid proc.c
- // to get acid [sic] output.
+ // to get acid [sic] output. Run once without the -a -o workdir/proc.acid in order to
+ // report compilation failures (the -o redirects all messages, unfortunately).
vreset(&argv);
vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar));
vadd(&argv, "-D");
@@ -252,8 +192,8 @@ ok:
vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
vadd(&argv, "-I");
vadd(&argv, bprintf(&b, "%s", workdir));
- vadd(&argv, "-a");
vadd(&argv, "-n");
+ vadd(&argv, "-a");
vadd(&argv, "-o");
vadd(&argv, bpathf(&b, "%s/proc.acid", workdir));
vadd(&argv, "proc.c");
@@ -284,8 +224,8 @@ ok:
aggr = "p";
else if(streq(fields.p[1], "Gobuf"))
aggr = "gobuf";
- else if(streq(fields.p[1], "WinCall"))
- aggr = "wincall";
+ else if(streq(fields.p[1], "LibCall"))
+ aggr = "libcall";
else if(streq(fields.p[1], "WinCallbackContext"))
aggr = "cbctxt";
else if(streq(fields.p[1], "SEH"))
@@ -329,7 +269,7 @@ ok:
vfree(&fields);
}
-// mkzsys writes zsys_$GOOS_$GOARCH.h,
+// mkzsys writes zsys_$GOOS_$GOARCH.s,
// which contains arch or os specific asm code.
//
void
@@ -365,10 +305,8 @@ mkzsys(char *dir, char *file)
}
static char *runtimedefs[] = {
+ "defs.c",
"proc.c",
- "iface.c",
- "hashmap.c",
- "chan.c",
"parfor.c",
};
diff --git a/src/cmd/dist/goc2c.c b/src/cmd/dist/goc2c.c
index f0fa04335..38627657e 100644
--- a/src/cmd/dist/goc2c.c
+++ b/src/cmd/dist/goc2c.c
@@ -85,11 +85,15 @@ enum {
String,
Slice,
Eface,
+ Complex128,
+ Float32,
+ Float64,
};
static struct {
char *name;
int size;
+ int rnd; // alignment
} type_table[] = {
/*
* variable sized first, for easy replacement.
@@ -105,6 +109,7 @@ static struct {
{"String", 8},
{"Slice", 12},
{"Eface", 8},
+ {"Complex128", 16},
/* fixed size */
{"float32", 4},
@@ -130,7 +135,7 @@ int structround = 4;
static void
bad_eof(void)
{
- fatal("%s:%ud: unexpected EOF\n", file, lineno);
+ fatal("%s:%d: unexpected EOF\n", file, lineno);
}
/* Free a list of parameters. */
@@ -295,9 +300,9 @@ read_package(void)
token = read_token_no_eof();
if (token == nil)
- fatal("%s:%ud: no token\n", file, lineno);
+ fatal("%s:%d: no token\n", file, lineno);
if (!streq(token, "package")) {
- fatal("%s:%ud: expected \"package\", got \"%s\"\n",
+ fatal("%s:%d: expected \"package\", got \"%s\"\n",
file, lineno, token);
}
return read_token_no_eof();
@@ -307,6 +312,9 @@ read_package(void)
static void
read_preprocessor_lines(void)
{
+ int first;
+
+ first = 1;
while (1) {
int c;
@@ -317,6 +325,10 @@ read_preprocessor_lines(void)
xungetc();
break;
}
+ if(first) {
+ first = 0;
+ xputchar('\n');
+ }
xputchar(c);
do {
c = getchar_update_lineno();
@@ -365,17 +377,24 @@ read_type(void)
/* Return the size of the given type. */
static int
-type_size(char *p)
+type_size(char *p, int *rnd)
{
int i;
- if(p[xstrlen(p)-1] == '*')
+ if(p[xstrlen(p)-1] == '*') {
+ *rnd = type_table[Uintptr].rnd;
return type_table[Uintptr].size;
+ }
+
+ if(streq(p, "Iface"))
+ p = "Eface";
for(i=0; type_table[i].name; i++)
- if(streq(type_table[i].name, p))
+ if(streq(type_table[i].name, p)) {
+ *rnd = type_table[i].rnd;
return type_table[i].size;
- fatal("%s:%ud: unknown type %s\n", file, lineno, p);
+ }
+ fatal("%s:%d: unknown type %s\n", file, lineno, p);
return 0;
}
@@ -398,18 +417,22 @@ read_params(int *poffset)
while (1) {
p = xmalloc(sizeof(struct params));
p->name = token;
- p->type = read_type();
p->next = nil;
*pp = p;
pp = &p->next;
- size = type_size(p->type);
- rnd = size;
- if(rnd > structround)
- rnd = structround;
- if(offset%rnd)
- offset += rnd - offset%rnd;
- offset += size;
+ if(streq(token, "...")) {
+ p->type = xstrdup("");
+ } else {
+ p->type = read_type();
+ rnd = 0;
+ size = type_size(p->type, &rnd);
+ if(rnd > structround)
+ rnd = structround;
+ if(offset%rnd)
+ offset += rnd - offset%rnd;
+ offset += size;
+ }
token = read_token_no_eof();
if (!streq(token, ","))
@@ -418,7 +441,7 @@ read_params(int *poffset)
}
}
if (!streq(token, ")")) {
- fatal("%s:%ud: expected '('\n",
+ fatal("%s:%d: expected '('\n",
file, lineno);
}
if (poffset != nil)
@@ -438,6 +461,7 @@ read_func_header(char **name, struct params **params, int *paramwid, struct para
lastline = -1;
while (1) {
+ read_preprocessor_lines();
token = read_token();
if (token == nil)
return 0;
@@ -460,7 +484,7 @@ read_func_header(char **name, struct params **params, int *paramwid, struct para
token = read_token();
if (token == nil || !streq(token, "(")) {
- fatal("%s:%ud: expected \"(\"\n",
+ fatal("%s:%d: expected \"(\"\n",
file, lineno);
}
*params = read_params(paramwid);
@@ -473,7 +497,7 @@ read_func_header(char **name, struct params **params, int *paramwid, struct para
token = read_token();
}
if (token == nil || !streq(token, "{")) {
- fatal("%s:%ud: expected \"{\"\n",
+ fatal("%s:%d: expected \"{\"\n",
file, lineno);
}
return 1;
@@ -500,8 +524,13 @@ write_6g_func_header(char *package, char *name, struct params *params,
int paramwid, struct params *rets)
{
int first, n;
+ struct params *p;
+
+ bwritef(output, "void\n");
+ if(!contains(name, "·"))
+ bwritef(output, "%s·", package);
+ bwritef(output, "%s(", name);
- bwritef(output, "void\n%s·%s(", package, name);
first = 1;
write_params(params, &first);
@@ -518,6 +547,24 @@ write_6g_func_header(char *package, char *name, struct params *params,
write_params(rets, &first);
bwritef(output, ")\n{\n");
+
+ for (p = rets; p != nil; p = p->next) {
+ if(streq(p->name, "..."))
+ continue;
+ if(streq(p->type, "Slice"))
+ bwritef(output, "\t%s.array = 0;\n\t%s.len = 0;\n\t%s.cap = 0;\n", p->name, p->name, p->name);
+ else if(streq(p->type, "String"))
+ bwritef(output, "\t%s.str = 0;\n\t%s.len = 0;\n", p->name, p->name);
+ else if(streq(p->type, "Eface"))
+ bwritef(output, "\t%s.type = 0;\n\t%s.data = 0;\n", p->name, p->name);
+ else if(streq(p->type, "Iface"))
+ bwritef(output, "\t%s.tab = 0;\n\t%s.data = 0;\n", p->name, p->name);
+ else if(streq(p->type, "Complex128"))
+ bwritef(output, "\t%s.real = 0;\n\t%s.imag = 0;\n", p->name, p->name);
+ else
+ bwritef(output, "\t%s = 0;\n", p->name);
+ bwritef(output, "\tFLUSH(&%s);\n", p->name);
+ }
}
/* Write a 6g function trailer. */
@@ -527,7 +574,8 @@ write_6g_func_trailer(struct params *rets)
struct params *p;
for (p = rets; p != nil; p = p->next)
- bwritef(output, "\tFLUSH(&%s);\n", p->name);
+ if(!streq(p->name, "..."))
+ bwritef(output, "\tFLUSH(&%s);\n", p->name);
bwritef(output, "}\n");
}
@@ -726,6 +774,7 @@ process_file(void)
void
goc2c(char *goc, char *c)
{
+ int i;
Buf in, out;
binit(&in);
@@ -739,13 +788,15 @@ goc2c(char *goc, char *c)
if(!gcc) {
if(streq(goarch, "amd64")) {
type_table[Uintptr].size = 8;
- type_table[Eface].size = 8+8;
- type_table[String].size = 16;
if(use64bitint) {
type_table[Int].size = 8;
- type_table[Uint].size = 8;
+ } else {
+ type_table[Int].size = 4;
}
- type_table[Slice].size = 8+2*type_table[Int].size;
+ structround = 8;
+ } else if(streq(goarch, "amd64p32")) {
+ type_table[Uintptr].size = 4;
+ type_table[Int].size = 4;
structround = 8;
} else {
// NOTE: These are set in the initializer,
@@ -753,13 +804,22 @@ goc2c(char *goc, char *c)
// previous invocation of goc2c, so we have
// to restore them.
type_table[Uintptr].size = 4;
- type_table[String].size = 8;
- type_table[Slice].size = 16;
- type_table[Eface].size = 4+4;
type_table[Int].size = 4;
- type_table[Uint].size = 4;
structround = 4;
}
+
+ type_table[Uint].size = type_table[Int].size;
+ type_table[Slice].size = type_table[Uintptr].size+2*type_table[Int].size;
+ type_table[Eface].size = 2*type_table[Uintptr].size;
+ type_table[String].size = 2*type_table[Uintptr].size;
+
+ for(i=0; i<nelem(type_table); i++)
+ type_table[i].rnd = type_table[i].size;
+
+ type_table[String].rnd = type_table[Uintptr].rnd;
+ type_table[Slice].rnd = type_table[Uintptr].rnd;
+ type_table[Eface].rnd = type_table[Uintptr].rnd;
+ type_table[Complex128].rnd = type_table[Float64].rnd;
}
bprintf(&out, "// auto generated by go tool dist\n// goos=%s goarch=%s\n\n", goos, goarch);
diff --git a/src/cmd/dist/unix.c b/src/cmd/dist/unix.c
index fa388e058..8b943a2d9 100644
--- a/src/cmd/dist/unix.c
+++ b/src/cmd/dist/unix.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include <stdarg.h>
#include <setjmp.h>
+#include <signal.h>
// bprintf replaces the buffer with the result of the printf formatting
// and returns a pointer to the NUL-terminated buffer contents.
@@ -686,6 +687,14 @@ main(int argc, char **argv)
gohostos = "openbsd";
#elif defined(__NetBSD__)
gohostos = "netbsd";
+#elif defined(__sun) && defined(__SVR4)
+ gohostos = "solaris";
+ // Even on 64-bit platform, solaris uname -m prints i86pc.
+ run(&b, nil, 0, "isainfo", "-n", nil);
+ if(contains(bstr(&b), "amd64"))
+ gohostarch = "amd64";
+ if(contains(bstr(&b), "i386"))
+ gohostarch = "386";
#else
fatal("unknown operating system");
#endif
diff --git a/src/cmd/dist/windows.c b/src/cmd/dist/windows.c
index 7d03989b2..2839c4bc5 100644
--- a/src/cmd/dist/windows.c
+++ b/src/cmd/dist/windows.c
@@ -840,34 +840,20 @@ void
xprintf(char *fmt, ...)
{
va_list arg;
- char *p;
- DWORD n, w;
-
+
va_start(arg, fmt);
- n = vsnprintf(NULL, 0, fmt, arg);
- p = xmalloc(n+1);
- vsnprintf(p, n+1, fmt, arg);
+ vprintf(fmt, arg);
va_end(arg);
- w = 0;
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), p, n, &w, 0);
- xfree(p);
}
void
errprintf(char *fmt, ...)
{
va_list arg;
- char *p;
- DWORD n, w;
-
+
va_start(arg, fmt);
- n = vsnprintf(NULL, 0, fmt, arg);
- p = xmalloc(n+1);
- vsnprintf(p, n+1, fmt, arg);
+ vfprintf(stderr, fmt, arg);
va_end(arg);
- w = 0;
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), p, n, &w, 0);
- xfree(p);
}
int
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c
index 8e9677e75..b809640e4 100644
--- a/src/cmd/gc/align.c
+++ b/src/cmd/gc/align.c
@@ -175,11 +175,11 @@ dowidth(Type *t)
case TFLOAT64:
case TCOMPLEX64:
w = 8;
- t->align = widthptr;
+ t->align = widthreg;
break;
case TCOMPLEX128:
w = 16;
- t->align = widthptr;
+ t->align = widthreg;
break;
case TPTR32:
w = 4;
@@ -288,10 +288,10 @@ dowidth(Type *t)
// compute their widths as side-effect.
t1 = t->type;
w = widstruct(t->type, *getthis(t1), 0, 0);
- w = widstruct(t->type, *getinarg(t1), w, widthptr);
- w = widstruct(t->type, *getoutarg(t1), w, widthptr);
+ w = widstruct(t->type, *getinarg(t1), w, widthreg);
+ w = widstruct(t->type, *getoutarg(t1), w, widthreg);
t1->argwid = w;
- if(w%widthptr)
+ if(w%widthreg)
warn("bad type %T %d\n", t1, w);
t->align = 1;
break;
diff --git a/src/cmd/gc/array.c b/src/cmd/gc/array.c
new file mode 100644
index 000000000..5e53c1ff0
--- /dev/null
+++ b/src/cmd/gc/array.c
@@ -0,0 +1,129 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <u.h>
+#include <libc.h>
+#include "go.h"
+
+enum {
+ DEFAULTCAPACITY = 16,
+};
+
+struct Array
+{
+ int32 length; // number of elements
+ int32 size; // element size
+ int32 capacity; // size of data in elements
+ char *data; // element storage
+};
+
+Array*
+arraynew(int32 capacity, int32 size)
+{
+ Array *result;
+
+ if(capacity < 0)
+ fatal("arraynew: capacity %d is not positive", capacity);
+ if(size < 0)
+ fatal("arraynew: size %d is not positive\n", size);
+ result = malloc(sizeof(*result));
+ if(result == nil)
+ fatal("arraynew: malloc failed\n");
+ result->length = 0;
+ result->size = size;
+ result->capacity = capacity == 0 ? DEFAULTCAPACITY : capacity;
+ result->data = malloc(result->capacity * result->size);
+ if(result->data == nil)
+ fatal("arraynew: malloc failed\n");
+ return result;
+}
+
+void
+arrayfree(Array *array)
+{
+ if(array == nil)
+ return;
+ free(array->data);
+ free(array);
+}
+
+int32
+arraylength(Array *array)
+{
+ return array->length;
+}
+
+void*
+arrayget(Array *array, int32 index)
+{
+ if(array == nil)
+ fatal("arrayget: array is nil\n");
+ if(index < 0 || index >= array->length)
+ fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length);
+ return array->data + index * array->size;
+}
+
+void
+arrayset(Array *array, int32 index, void *element)
+{
+ if(array == nil)
+ fatal("arrayset: array is nil\n");
+ if(element == nil)
+ fatal("arrayset: element is nil\n");
+ if(index < 0 || index >= array->length)
+ fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length);
+ memmove(array->data + index * array->size, element, array->size);
+}
+
+static void
+ensurecapacity(Array *array, int32 capacity)
+{
+ int32 newcapacity;
+ char *newdata;
+
+ if(array == nil)
+ fatal("ensurecapacity: array is nil\n");
+ if(capacity < 0)
+ fatal("ensurecapacity: capacity %d is not positive", capacity);
+ if(capacity >= array->capacity) {
+ newcapacity = capacity + (capacity >> 1);
+ newdata = realloc(array->data, newcapacity * array->size);
+ if(newdata == nil)
+ fatal("ensurecapacity: realloc failed\n");
+ array->capacity = newcapacity;
+ array->data = newdata;
+ }
+}
+
+void
+arrayadd(Array *array, void *element)
+{
+ if(array == nil)
+ fatal("arrayset: array is nil\n");
+ if(element == nil)
+ fatal("arrayset: element is nil\n");
+ ensurecapacity(array, array->length + 1);
+ array->length++;
+ arrayset(array, array->length - 1, element);
+}
+
+int32
+arrayindexof(Array *array, void *element)
+{
+ void *p;
+ int32 i;
+
+ for(i = 0; i < array->length; i++) {
+ p = arrayget(array, i);
+ if(memcmp(p, &element, array->size) == 0)
+ return i;
+ }
+ return -1;
+}
+
+void
+arraysort(Array *array, int (*cmp)(const void*, const void*))
+{
+ qsort(array->data, array->length, array->size, cmp);
+}
diff --git a/src/cmd/gc/bits.c b/src/cmd/gc/bits.c
index c0fd4d85e..2e79f6f1d 100644
--- a/src/cmd/gc/bits.c
+++ b/src/cmd/gc/bits.c
@@ -153,7 +153,7 @@ Qconv(Fmt *fp)
if(var[i].node == N || var[i].node->sym == S)
fmtprint(fp, "$%d", i);
else {
- fmtprint(fp, "%s", var[i].node->sym->name);
+ fmtprint(fp, "%s(%d)", var[i].node->sym->name, i);
if(var[i].offset != 0)
fmtprint(fp, "%+lld", (vlong)var[i].offset);
}
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
index 309dc1ea0..5ca5aeb77 100644
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -5,6 +5,7 @@ char *runtimeimport =
"func @\"\".new (@\"\".typ·2 *byte) (? *any)\n"
"func @\"\".panicindex ()\n"
"func @\"\".panicslice ()\n"
+ "func @\"\".panicdivide ()\n"
"func @\"\".throwreturn ()\n"
"func @\"\".throwinit ()\n"
"func @\"\".panicwrap (? string, ? string, ? string)\n"
@@ -23,11 +24,16 @@ char *runtimeimport =
"func @\"\".printnl ()\n"
"func @\"\".printsp ()\n"
"func @\"\".goprintf ()\n"
- "func @\"\".concatstring ()\n"
+ "func @\"\".concatstring2 (? string, ? string) (? string)\n"
+ "func @\"\".concatstring3 (? string, ? string, ? string) (? string)\n"
+ "func @\"\".concatstring4 (? string, ? string, ? string, ? string) (? string)\n"
+ "func @\"\".concatstring5 (? string, ? string, ? string, ? string, ? string) (? string)\n"
+ "func @\"\".concatstrings (? []string) (? string)\n"
"func @\"\".cmpstring (? string, ? string) (? int)\n"
"func @\"\".eqstring (? string, ? string) (? bool)\n"
"func @\"\".intstring (? int64) (? string)\n"
"func @\"\".slicebytetostring (? []byte) (? string)\n"
+ "func @\"\".slicebytetostringtmp (? []byte) (? string)\n"
"func @\"\".slicerunetostring (? []rune) (? string)\n"
"func @\"\".stringtoslicebyte (? string) (? []byte)\n"
"func @\"\".stringtoslicerune (? string) (? []rune)\n"
@@ -38,8 +44,8 @@ char *runtimeimport =
"func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n"
"func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n"
"func @\"\".convI2I (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
- "func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
- "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 any) (@\"\".ret·1 any)\n"
+ "func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 *any) (@\"\".ret·1 any)\n"
+ "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 *any) (@\"\".ret·1 any)\n"
"func @\"\".assertE2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
"func @\"\".assertE2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
"func @\"\".assertE2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
@@ -60,26 +66,24 @@ char *runtimeimport =
"func @\"\".efacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
"func @\"\".equal (@\"\".typ·2 *byte, @\"\".x1·3 any, @\"\".x2·4 any) (@\"\".ret·1 bool)\n"
"func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64) (@\"\".hmap·1 map[any]any)\n"
- "func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 any)\n"
+ "func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 *any) (@\"\".val·1 *any)\n"
"func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
"func @\"\".mapaccess1_fast64 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
"func @\"\".mapaccess1_faststr (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
- "func @\"\".mapaccess2 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 any, @\"\".pres·2 bool)\n"
+ "func @\"\".mapaccess2 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 *any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
"func @\"\".mapaccess2_fast32 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
"func @\"\".mapaccess2_fast64 (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
"func @\"\".mapaccess2_faststr (@\"\".mapType·3 *byte, @\"\".hmap·4 map[any]any, @\"\".key·5 any) (@\"\".val·1 *any, @\"\".pres·2 bool)\n"
- "func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 any, @\"\".val·4 any)\n"
+ "func @\"\".mapassign1 (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any, @\"\".val·4 *any)\n"
"func @\"\".mapiterinit (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".hiter·3 *any)\n"
- "func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 any)\n"
+ "func @\"\".mapdelete (@\"\".mapType·1 *byte, @\"\".hmap·2 map[any]any, @\"\".key·3 *any)\n"
"func @\"\".mapiternext (@\"\".hiter·1 *any)\n"
- "func @\"\".mapiter1 (@\"\".hiter·2 *any) (@\"\".key·1 any)\n"
- "func @\"\".mapiter2 (@\"\".hiter·3 *any) (@\"\".key·1 any, @\"\".val·2 any)\n"
"func @\"\".makechan (@\"\".chanType·2 *byte, @\"\".hint·3 int64) (@\"\".hchan·1 chan any)\n"
- "func @\"\".chanrecv1 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any) (@\"\".elem·1 any)\n"
- "func @\"\".chanrecv2 (@\"\".chanType·3 *byte, @\"\".hchan·4 <-chan any) (@\"\".elem·1 any, @\"\".received·2 bool)\n"
- "func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 any)\n"
+ "func @\"\".chanrecv1 (@\"\".chanType·1 *byte, @\"\".hchan·2 <-chan any, @\"\".elem·3 *any)\n"
+ "func @\"\".chanrecv2 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (? bool)\n"
+ "func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 *any)\n"
"func @\"\".closechan (@\"\".hchan·1 any)\n"
- "func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 any) (? bool)\n"
+ "func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n"
"func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n"
"func @\"\".selectnbrecv2 (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".received·4 *bool, @\"\".hchan·5 <-chan any) (? bool)\n"
"func @\"\".newselect (@\"\".size·2 int32) (@\"\".sel·1 *byte)\n"
diff --git a/src/cmd/gc/bv.c b/src/cmd/gc/bv.c
index 92834a97b..2efbbc565 100644
--- a/src/cmd/gc/bv.c
+++ b/src/cmd/gc/bv.c
@@ -11,12 +11,24 @@ enum {
WORDBITS = 32,
};
-uintptr
+static uintptr
bvsize(uintptr n)
{
return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE;
}
+int32
+bvbits(Bvec *bv)
+{
+ return bv->n;
+}
+
+int32
+bvwords(Bvec *bv)
+{
+ return (bv->n + WORDBITS - 1) / WORDBITS;
+}
+
Bvec*
bvalloc(int32 n)
{
@@ -34,26 +46,49 @@ bvalloc(int32 n)
return bv;
}
+/* difference */
void
-bvset(Bvec *bv, int32 i)
+bvandnot(Bvec *dst, Bvec *src1, Bvec *src2)
{
- uint32 mask;
+ int32 i, w;
- if(i < 0 || i >= bv->n)
- fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n);
- mask = 1U << (i % WORDBITS);
- bv->b[i / WORDBITS] |= mask;
+ if(dst->n != src1->n || dst->n != src2->n)
+ fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
+ for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
+ dst->b[w] = src1->b[w] & ~src2->b[w];
+}
+
+int
+bvcmp(Bvec *bv1, Bvec *bv2)
+{
+ uintptr nbytes;
+
+ if(bv1->n != bv2->n)
+ fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n);
+ nbytes = bvsize(bv1->n);
+ return memcmp(bv1->b, bv2->b, nbytes);
}
void
-bvres(Bvec *bv, int32 i)
+bvcopy(Bvec *dst, Bvec *src)
{
- uint32 mask;
+ memmove(dst->b, src->b, bvsize(dst->n));
+}
- if(i < 0 || i >= bv->n)
- fatal("bvres: index %d is out of bounds with length %d\n", i, bv->n);
- mask = ~(1 << (i % WORDBITS));
- bv->b[i / WORDBITS] &= mask;
+Bvec*
+bvconcat(Bvec *src1, Bvec *src2)
+{
+ Bvec *dst;
+ int32 i;
+
+ dst = bvalloc(src1->n + src2->n);
+ for(i = 0; i < src1->n; i++)
+ if(bvget(src1, i))
+ bvset(dst, i);
+ for(i = 0; i < src2->n; i++)
+ if(bvget(src2, i))
+ bvset(dst, i + src1->n);
+ return dst;
}
int
@@ -63,7 +98,7 @@ bvget(Bvec *bv, int32 i)
if(i < 0 || i >= bv->n)
fatal("bvget: index %d is out of bounds with length %d\n", i, bv->n);
- mask = 1 << (i % WORDBITS);
+ mask = 1U << (i % WORDBITS);
word = bv->b[i / WORDBITS] & mask;
return word ? 1 : 0;
}
@@ -78,3 +113,74 @@ bvisempty(Bvec *bv)
return 0;
return 1;
}
+
+void
+bvnot(Bvec *bv)
+{
+ int32 i, w;
+
+ for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++)
+ bv->b[w] = ~bv->b[w];
+}
+
+/* union */
+void
+bvor(Bvec *dst, Bvec *src1, Bvec *src2)
+{
+ int32 i, w;
+
+ if(dst->n != src1->n || dst->n != src2->n)
+ fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
+ for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
+ dst->b[w] = src1->b[w] | src2->b[w];
+}
+
+/* intersection */
+void
+bvand(Bvec *dst, Bvec *src1, Bvec *src2)
+{
+ int32 i, w;
+
+ if(dst->n != src1->n || dst->n != src2->n)
+ fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
+ for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
+ dst->b[w] = src1->b[w] & src2->b[w];
+}
+
+void
+bvprint(Bvec *bv)
+{
+ int32 i;
+
+ print("#*");
+ for(i = 0; i < bv->n; i++)
+ print("%d", bvget(bv, i));
+}
+
+void
+bvreset(Bvec *bv, int32 i)
+{
+ uint32 mask;
+
+ if(i < 0 || i >= bv->n)
+ fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n);
+ mask = ~(1 << (i % WORDBITS));
+ bv->b[i / WORDBITS] &= mask;
+}
+
+void
+bvresetall(Bvec *bv)
+{
+ memset(bv->b, 0x00, bvsize(bv->n));
+}
+
+void
+bvset(Bvec *bv, int32 i)
+{
+ uint32 mask;
+
+ if(i < 0 || i >= bv->n)
+ fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n);
+ mask = 1U << (i % WORDBITS);
+ bv->b[i / WORDBITS] |= mask;
+}
diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c
index 5a84dfb1b..ad4e5bd02 100644
--- a/src/cmd/gc/closure.c
+++ b/src/cmd/gc/closure.c
@@ -161,6 +161,7 @@ makeclosure(Node *func)
// and initialize in entry prologue.
body = nil;
offset = widthptr;
+ xfunc->needctxt = func->cvars != nil;
for(l=func->cvars; l; l=l->next) {
v = l->n;
if(v->op == 0)
@@ -252,6 +253,14 @@ walkclosure(Node *func, NodeList **init)
// typecheck will insert a PTRLIT node under CONVNOP,
// tag it with escape analysis result.
clos->left->esc = func->esc;
+ // non-escaping temp to use, if any.
+ // orderexpr did not compute the type; fill it in now.
+ if(func->alloc != N) {
+ func->alloc->type = clos->left->left->type;
+ func->alloc->orig->type = func->alloc->type;
+ clos->left->right = func->alloc;
+ func->alloc = N;
+ }
walkexpr(&clos, init);
return clos;
@@ -361,9 +370,12 @@ makepartialcall(Node *fn, Type *t0, Node *meth)
// Declare and initialize variable holding receiver.
body = nil;
+ xfunc->needctxt = 1;
cv = nod(OCLOSUREVAR, N, N);
cv->xoffset = widthptr;
cv->type = rcvrtype;
+ if(cv->type->align > widthptr)
+ cv->xoffset = cv->type->align;
ptr = nod(ONAME, N, N);
ptr->sym = lookup("rcvr");
ptr->class = PAUTO;
@@ -441,6 +453,14 @@ walkpartialcall(Node *n, NodeList **init)
// typecheck will insert a PTRLIT node under CONVNOP,
// tag it with escape analysis result.
clos->left->esc = n->esc;
+ // non-escaping temp to use, if any.
+ // orderexpr did not compute the type; fill it in now.
+ if(n->alloc != N) {
+ n->alloc->type = clos->left->left->type;
+ n->alloc->orig->type = n->alloc->type;
+ clos->left->right = n->alloc;
+ n->alloc = N;
+ }
walkexpr(&clos, init);
return clos;
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index cfb1f0ade..143c1730d 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -22,19 +22,22 @@ Mpflt*
truncfltlit(Mpflt *oldv, Type *t)
{
double d;
- float f;
Mpflt *fv;
+ Val v;
if(t == T)
return oldv;
+ memset(&v, 0, sizeof v);
+ v.ctype = CTFLT;
+ v.u.fval = oldv;
+ overflow(v, t);
+
fv = mal(sizeof *fv);
*fv = *oldv;
// convert large precision literal floating
// into limited precision (float64 or float32)
- // botch -- this assumes that compiler fp
- // has same precision as runtime fp
switch(t->etype) {
case TFLOAT64:
d = mpgetflt(fv);
@@ -42,10 +45,9 @@ truncfltlit(Mpflt *oldv, Type *t)
break;
case TFLOAT32:
- d = mpgetflt(fv);
- f = d;
- d = f;
+ d = mpgetflt32(fv);
mpmovecflt(fv, d);
+
break;
}
return fv;
@@ -235,7 +237,6 @@ convlit1(Node **np, Type *t, int explicit)
n->val = toflt(n->val);
// flowthrough
case CTFLT:
- overflow(n->val, t);
n->val.u.fval = truncfltlit(n->val.u.fval, t);
break;
}
@@ -521,6 +522,7 @@ evconst(Node *n)
int wl, wr, lno, et;
Val v, rv;
Mpint b;
+ NodeList *l1, *l2;
// pick off just the opcodes that can be
// constant evaluated.
@@ -528,7 +530,6 @@ evconst(Node *n)
default:
return;
case OADD:
- case OADDSTR:
case OAND:
case OANDAND:
case OANDNOT:
@@ -559,6 +560,47 @@ evconst(Node *n)
if(!okforconst[n->type->etype] && n->type->etype != TNIL)
return;
break;
+
+ case OADDSTR:
+ // merge adjacent constants in the argument list.
+ for(l1=n->list; l1 != nil; l1= l1->next) {
+ if(isconst(l1->n, CTSTR) && l1->next != nil && isconst(l1->next->n, CTSTR)) {
+ l2 = l1;
+ len = 0;
+ while(l2 != nil && isconst(l2->n, CTSTR)) {
+ nr = l2->n;
+ len += nr->val.u.sval->len;
+ l2 = l2->next;
+ }
+ // merge from l1 up to but not including l2
+ str = mal(sizeof(*str) + len);
+ str->len = len;
+ len = 0;
+ l2 = l1;
+ while(l2 != nil && isconst(l2->n, CTSTR)) {
+ nr = l2->n;
+ memmove(str->s+len, nr->val.u.sval->s, nr->val.u.sval->len);
+ len += nr->val.u.sval->len;
+ l2 = l2->next;
+ }
+ nl = nod(OXXX, N, N);
+ *nl = *l1->n;
+ nl->orig = nl;
+ nl->val.ctype = CTSTR;
+ nl->val.u.sval = str;
+ l1->n = nl;
+ l1->next = l2;
+ }
+ }
+ // fix list end pointer.
+ for(l2=n->list; l2 != nil; l2=l2->next)
+ n->list->end = l2;
+ // collapse single-constant list to single constant.
+ if(count(n->list) == 1 && isconst(n->list->n, CTSTR)) {
+ n->op = OLITERAL;
+ n->val = n->list->n->val;
+ }
+ return;
}
nl = n->left;
@@ -861,15 +903,6 @@ evconst(Node *n)
if(cmpslit(nl, nr) > 0)
goto settrue;
goto setfalse;
- case TUP(OADDSTR, CTSTR):
- len = v.u.sval->len + rv.u.sval->len;
- str = mal(sizeof(*str) + len);
- str->len = len;
- memcpy(str->s, v.u.sval->s, v.u.sval->len);
- memcpy(str->s+v.u.sval->len, rv.u.sval->s, rv.u.sval->len);
- str->len = len;
- v.u.sval = str;
- break;
case TUP(OOROR, CTBOOL):
if(v.u.bval || rv.u.bval)
@@ -918,6 +951,7 @@ unary:
case TUP(OCONV, CTFLT):
case TUP(OCONV, CTSTR):
convlit1(&nl, n->type, 1);
+ v = nl->val;
break;
case TUP(OPLUS, CTINT):
@@ -1144,7 +1178,10 @@ defaultlit(Node **np, Type *t)
}
if(n->val.ctype == CTNIL) {
lineno = lno;
- yyerror("use of untyped nil");
+ if(!n->diag) {
+ yyerror("use of untyped nil");
+ n->diag = 1;
+ }
n->type = T;
break;
}
@@ -1559,7 +1596,7 @@ isgoconst(Node *n)
case ONAME:
l = n->sym->def;
- if(l->op == OLITERAL && n->val.ctype != CTNIL)
+ if(l && l->op == OLITERAL && n->val.ctype != CTNIL)
return 1;
break;
@@ -1594,10 +1631,25 @@ hascallchan(Node *n)
if(n == N)
return 0;
switch(n->op) {
+ case OAPPEND:
case OCALL:
case OCALLFUNC:
- case OCALLMETH:
case OCALLINTER:
+ case OCALLMETH:
+ case OCAP:
+ case OCLOSE:
+ case OCOMPLEX:
+ case OCOPY:
+ case ODELETE:
+ case OIMAG:
+ case OLEN:
+ case OMAKE:
+ case ONEW:
+ case OPANIC:
+ case OPRINT:
+ case OPRINTN:
+ case OREAL:
+ case ORECOVER:
case ORECV:
return 1;
}
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index c7d13ef06..73c2581be 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -130,7 +130,7 @@ dumpdcl(char *st)
}
print(" '%s'", d->name);
s = pkglookup(d->name, d->pkg);
- print(" %lS\n", s);
+ print(" %S\n", s);
}
}
@@ -643,8 +643,8 @@ funcargs(Node *nt)
fatal("funcargs out %O", n->op);
if(n->left == N) {
- // give it a name so escape analysis has nodes to work with
- snprint(namebuf, sizeof(namebuf), "~anon%d", gen++);
+ // Name so that escape analysis can track it. ~r stands for 'result'.
+ snprint(namebuf, sizeof(namebuf), "~r%d", gen++);
n->left = newname(lookup(namebuf));
// TODO: n->left->missing = 1;
}
@@ -652,14 +652,20 @@ funcargs(Node *nt)
n->left->op = ONAME;
if(isblank(n->left)) {
- // Give it a name so we can assign to it during return.
- // preserve the original in ->orig
+ // Give it a name so we can assign to it during return. ~b stands for 'blank'.
+ // The name must be different from ~r above because if you have
+ // func f() (_ int)
+ // func g() int
+ // f is allowed to use a plain 'return' with no arguments, while g is not.
+ // So the two cases must be distinguished.
+ // We do not record a pointer to the original node (n->orig).
+ // Having multiple names causes too much confusion in later passes.
nn = nod(OXXX, N, N);
*nn = *n->left;
+ nn->orig = nn;
+ snprint(namebuf, sizeof(namebuf), "~b%d", gen++);
+ nn->sym = lookup(namebuf);
n->left = nn;
-
- snprint(namebuf, sizeof(namebuf), "~anon%d", gen++);
- n->left->sym = lookup(namebuf);
}
n->left->ntype = n->right;
@@ -941,8 +947,6 @@ interfacefield(Node *n)
f->nname = n->left;
f->embedded = n->embedded;
f->sym = f->nname->sym;
- if(importpkg && !exportname(f->sym->name))
- f->sym = pkglookup(f->sym->name, structpkg);
}
} else {
@@ -1211,7 +1215,7 @@ functype(Node *this, NodeList *in, NodeList *out)
t->outnamed = 0;
if(t->outtuple > 0 && out->n->left != N && out->n->left->orig != N) {
s = out->n->left->orig->sym;
- if(s != S && s->name[0] != '~')
+ if(s != S && (s->name[0] != '~' || s->name[1] != 'r')) // ~r%d is the name invented for an unnamed result
t->outnamed = 1;
}
@@ -1434,6 +1438,8 @@ funccompile(Node *n, int isclosure)
// record offset to actual frame pointer.
// for closure, have to skip over leading pointers and PC slot.
+ // TODO(rsc): this is the old jit closure handling code.
+ // with the new closures, isclosure is always 0; delete this block.
nodfp->xoffset = 0;
if(isclosure) {
NodeList *l;
diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go
index 791967708..03df93a3e 100644
--- a/src/cmd/gc/doc.go
+++ b/src/cmd/gc/doc.go
@@ -37,6 +37,8 @@ Substitute 6g with 8g or 5g where appropriate.
Flags:
-o file
output file, default file.6 for 6g, etc.
+ -pack
+ write an archive file rather than an object file
-e
normally the compiler quits after 10 errors; -e prints all errors
-p path
@@ -50,12 +52,14 @@ Flags:
add dir1 and dir2 to the list of paths to check for imported packages
-N
disable optimizations
+ -nolocalimports
+ disallow local (relative) imports
-S
write assembly language text to standard output (code only)
-S -S
write assembly language text to standard output (code and data)
-u
- disallow importing packages not marked as safe
+ disallow importing packages not marked as safe; implies -nolocalimports
-V
print the compiler version
-race
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index b84b66ef1..78624d7cb 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -185,12 +185,12 @@ visitcode(Node *n, uint32 min)
typedef struct EscState EscState;
static void escfunc(EscState*, Node *func);
-static void esclist(EscState*, NodeList *l);
-static void esc(EscState*, Node *n);
+static void esclist(EscState*, NodeList *l, Node *up);
+static void esc(EscState*, Node *n, Node *up);
static void escloopdepthlist(EscState*, NodeList *l);
static void escloopdepth(EscState*, Node *n);
static void escassign(EscState*, Node *dst, Node *src);
-static void esccall(EscState*, Node*);
+static void esccall(EscState*, Node*, Node *up);
static void escflows(EscState*, Node *dst, Node *src);
static void escflood(EscState*, Node *dst);
static void escwalk(EscState*, int level, Node *dst, Node *src);
@@ -204,6 +204,13 @@ struct EscState {
// flow to.
Node theSink;
+ // If an analyzed function is recorded to return
+ // pieces obtained via indirection from a parameter,
+ // and later there is a call f(x) to that function,
+ // we create a link funcParam <- x to record that fact.
+ // The funcParam node is handled specially in escflood.
+ Node funcParam;
+
NodeList* dsts; // all dst nodes
int loopdepth; // for detecting nested loop scopes
int pdepth; // for debug printing in recursions.
@@ -269,7 +276,13 @@ analyze(NodeList *all, int recursive)
e->theSink.sym = lookup(".sink");
e->theSink.escloopdepth = -1;
e->recursive = recursive;
-
+
+ e->funcParam.op = ONAME;
+ e->funcParam.orig = &e->funcParam;
+ e->funcParam.class = PAUTO;
+ e->funcParam.sym = lookup(".param");
+ e->funcParam.escloopdepth = 10000000;
+
for(l=all; l; l=l->next)
if(l->n->op == ODCLFUNC)
l->n->esc = EscFuncPlanned;
@@ -328,6 +341,7 @@ escfunc(EscState *e, Node *func)
ll->n->escloopdepth = 0;
break;
case PPARAM:
+ ll->n->escloopdepth = 1;
if(ll->n->type && !haspointers(ll->n->type))
break;
if(curfn->nbody == nil && !curfn->noescape)
@@ -335,7 +349,6 @@ escfunc(EscState *e, Node *func)
else
ll->n->esc = EscNone; // prime for escflood later
e->noesc = list(e->noesc, ll->n);
- ll->n->escloopdepth = 1;
break;
}
}
@@ -347,7 +360,7 @@ escfunc(EscState *e, Node *func)
escflows(e, &e->theSink, ll->n);
escloopdepthlist(e, curfn->nbody);
- esclist(e, curfn->nbody);
+ esclist(e, curfn->nbody, curfn);
curfn = savefn;
e->loopdepth = saveld;
}
@@ -405,14 +418,14 @@ escloopdepth(EscState *e, Node *n)
}
static void
-esclist(EscState *e, NodeList *l)
+esclist(EscState *e, NodeList *l, Node *up)
{
for(; l; l=l->next)
- esc(e, l->n);
+ esc(e, l->n, up);
}
static void
-esc(EscState *e, Node *n)
+esc(EscState *e, Node *n, Node *up)
{
int lno;
NodeList *ll, *lr;
@@ -423,18 +436,32 @@ esc(EscState *e, Node *n)
lno = setlineno(n);
+ // ninit logically runs at a different loopdepth than the rest of the for loop.
+ esclist(e, n->ninit, n);
+
if(n->op == OFOR || n->op == ORANGE)
e->loopdepth++;
- esc(e, n->left);
- esc(e, n->right);
- esc(e, n->ntest);
- esc(e, n->nincr);
- esclist(e, n->ninit);
- esclist(e, n->nbody);
- esclist(e, n->nelse);
- esclist(e, n->list);
- esclist(e, n->rlist);
+ // type switch variables have no ODCL.
+ // process type switch as declaration.
+ // must happen before processing of switch body,
+ // so before recursion.
+ if(n->op == OSWITCH && n->ntest && n->ntest->op == OTYPESW) {
+ for(ll=n->list; ll; ll=ll->next) { // cases
+ // ll->n->nname is the variable per case
+ if(ll->n->nname)
+ ll->n->nname->escloopdepth = e->loopdepth;
+ }
+ }
+
+ esc(e, n->left, n);
+ esc(e, n->right, n);
+ esc(e, n->ntest, n);
+ esc(e, n->nincr, n);
+ esclist(e, n->nbody, n);
+ esclist(e, n->nelse, n);
+ esclist(e, n->list, n);
+ esclist(e, n->rlist, n);
if(n->op == OFOR || n->op == ORANGE)
e->loopdepth--;
@@ -520,7 +547,7 @@ esc(EscState *e, Node *n)
case OCALLMETH:
case OCALLFUNC:
case OCALLINTER:
- esccall(e, n);
+ esccall(e, n, up);
break;
case OAS2FUNC: // x,y = f()
@@ -628,7 +655,6 @@ esc(EscState *e, Node *n)
escassign(e, n, a);
}
// fallthrough
- case OADDR:
case OMAKECHAN:
case OMAKEMAP:
case OMAKESLICE:
@@ -637,6 +663,35 @@ esc(EscState *e, Node *n)
n->esc = EscNone; // until proven otherwise
e->noesc = list(e->noesc, n);
break;
+
+ case OADDR:
+ n->esc = EscNone; // until proven otherwise
+ e->noesc = list(e->noesc, n);
+ // current loop depth is an upper bound on actual loop depth
+ // of addressed value.
+ n->escloopdepth = e->loopdepth;
+ // for &x, use loop depth of x if known.
+ // it should always be known, but if not, be conservative
+ // and keep the current loop depth.
+ if(n->left->op == ONAME) {
+ switch(n->left->class) {
+ case PAUTO:
+ if(n->left->escloopdepth != 0)
+ n->escloopdepth = n->left->escloopdepth;
+ break;
+ case PPARAM:
+ case PPARAMOUT:
+ // PPARAM is loop depth 1 always.
+ // PPARAMOUT is loop depth 0 for writes
+ // but considered loop depth 1 for address-of,
+ // so that writing the address of one result
+ // to another (or the same) result makes the
+ // first result move to the heap.
+ n->escloopdepth = 1;
+ break;
+ }
+ }
+ break;
}
lineno = lno;
@@ -748,8 +803,8 @@ escassign(EscState *e, Node *dst, Node *src)
case ODOTTYPE:
case ODOTTYPE2:
case OSLICE:
- case OSLICEARR:
case OSLICE3:
+ case OSLICEARR:
case OSLICE3ARR:
// Conversions, field access, slice all preserve the input value.
escassign(e, dst, src->left);
@@ -792,24 +847,34 @@ escassign(EscState *e, Node *dst, Node *src)
lineno = lno;
}
-static void
+static int
escassignfromtag(EscState *e, Strlit *note, NodeList *dsts, Node *src)
{
- int em;
+ int em, em0;
em = parsetag(note);
-
+
if(em == EscUnknown) {
escassign(e, &e->theSink, src);
- return;
+ return em;
}
-
- for(em >>= EscBits; em && dsts; em >>= 1, dsts=dsts->next)
+
+ if(em == EscNone)
+ return em;
+
+ // If content inside parameter (reached via indirection)
+ // escapes back to results, mark as such.
+ if(em & EscContentEscapes)
+ escassign(e, &e->funcParam, src);
+
+ em0 = em;
+ for(em >>= EscReturnBits; em && dsts; em >>= 1, dsts=dsts->next)
if(em & 1)
escassign(e, dsts->n, src);
if (em != 0 && dsts == nil)
fatal("corrupt esc tag %Z or messed up escretval list\n", note);
+ return em0;
}
// This is a bit messier than fortunate, pulled out of esc's big
@@ -819,7 +884,7 @@ escassignfromtag(EscState *e, Strlit *note, NodeList *dsts, Node *src)
// different for methods vs plain functions and for imported vs
// this-package
static void
-esccall(EscState *e, Node *n)
+esccall(EscState *e, Node *n, Node *up)
{
NodeList *ll, *lr;
Node *a, *fn, *src;
@@ -856,7 +921,7 @@ esccall(EscState *e, Node *n)
if(a->type->etype == TSTRUCT && a->type->funarg) // f(g()).
ll = a->escretval;
}
-
+
if(fn && fn->op == ONAME && fn->class == PFUNC && fn->defn && fn->defn->nbody && fn->ntype && fn->defn->esc < EscFuncTagged) {
// function in same mutually recursive group. Incorporate into flow graph.
// print("esc local fn: %N\n", fn->ntype);
@@ -876,6 +941,10 @@ esccall(EscState *e, Node *n)
if(lr->n->isddd && !n->isddd) {
// Introduce ODDDARG node to represent ... allocation.
src = nod(ODDDARG, N, N);
+ src->type = typ(TARRAY);
+ src->type->type = lr->n->type->type;
+ src->type->bound = count(ll);
+ src->type = ptrto(src->type); // make pointer so it will be tracked
src->escloopdepth = e->loopdepth;
src->lineno = n->lineno;
src->esc = EscNone; // until we find otherwise
@@ -916,8 +985,12 @@ esccall(EscState *e, Node *n)
// print("esc analyzed fn: %#N (%+T) returning (%+H)\n", fn, fntype, n->escretval);
// Receiver.
- if(n->op != OCALLFUNC)
- escassignfromtag(e, getthisx(fntype)->type->note, n->escretval, n->left->left);
+ if(n->op != OCALLFUNC) {
+ t = getthisx(fntype)->type;
+ src = n->left->left;
+ if(haspointers(t->type))
+ escassignfromtag(e, t->note, n->escretval, src);
+ }
for(t=getinargx(fntype)->type; ll; ll=ll->next) {
src = ll->n;
@@ -926,11 +999,40 @@ esccall(EscState *e, Node *n)
src = nod(ODDDARG, N, N);
src->escloopdepth = e->loopdepth;
src->lineno = n->lineno;
+ src->type = typ(TARRAY);
+ src->type->type = t->type->type;
+ src->type->bound = count(ll);
+ src->type = ptrto(src->type); // make pointer so it will be tracked
src->esc = EscNone; // until we find otherwise
e->noesc = list(e->noesc, src);
n->right = src;
}
- escassignfromtag(e, t->note, n->escretval, src);
+ if(haspointers(t->type)) {
+ if(escassignfromtag(e, t->note, n->escretval, src) == EscNone && up->op != ODEFER && up->op != OPROC) {
+ a = src;
+ while(a->op == OCONVNOP)
+ a = a->left;
+ switch(a->op) {
+ case OCALLPART:
+ case OCLOSURE:
+ case ODDDARG:
+ case OARRAYLIT:
+ case OPTRLIT:
+ case OSTRUCTLIT:
+ // The callee has already been analyzed, so its arguments have esc tags.
+ // The argument is marked as not escaping at all.
+ // Record that fact so that any temporary used for
+ // synthesizing this expression can be reclaimed when
+ // the function returns.
+ // This 'noescape' is even stronger than the usual esc == EscNone.
+ // src->esc == EscNone means that src does not escape the current function.
+ // src->noescape = 1 here means that src does not escape this statement
+ // in the current function.
+ a->noescape = 1;
+ break;
+ }
+ }
+ }
if(src != ll->n)
break;
t = t->down;
@@ -1029,19 +1131,30 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
// Input parameter flowing to output parameter?
if(dst->op == ONAME && dst->class == PPARAMOUT && dst->vargen <= 20) {
- if(src->op == ONAME && src->class == PPARAM && level == 0 && src->curfn == dst->curfn) {
- if(src->esc != EscScope && src->esc != EscHeap) {
+ if(src->op == ONAME && src->class == PPARAM && src->curfn == dst->curfn && src->esc != EscScope && src->esc != EscHeap) {
+ if(level == 0) {
if(debug['m'])
warnl(src->lineno, "leaking param: %hN to result %S", src, dst->sym);
if((src->esc&EscMask) != EscReturn)
src->esc = EscReturn;
- src->esc |= 1<<((dst->vargen-1) + EscBits);
+ src->esc |= 1<<((dst->vargen-1) + EscReturnBits);
+ goto recurse;
+ } else if(level > 0) {
+ if(debug['m'])
+ warnl(src->lineno, "%N leaking param %hN content to result %S", src->curfn->nname, src, dst->sym);
+ if((src->esc&EscMask) != EscReturn)
+ src->esc = EscReturn;
+ src->esc |= EscContentEscapes;
goto recurse;
}
}
}
- leaks = (level <= 0) && (dst->escloopdepth < src->escloopdepth);
+ // The second clause is for values pointed at by an object passed to a call
+ // that returns something reached via indirect from the object.
+ // We don't know which result it is or how many indirects, so we treat it as leaking.
+ leaks = level <= 0 && dst->escloopdepth < src->escloopdepth ||
+ level < 0 && dst == &e->funcParam && haspointers(src->type);
switch(src->op) {
case ONAME:
@@ -1094,6 +1207,10 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
break;
case ODOT:
+ case OSLICE:
+ case OSLICEARR:
+ case OSLICE3:
+ case OSLICE3ARR:
escwalk(e, level, dst, src->left);
break;
@@ -1103,7 +1220,6 @@ escwalk(EscState *e, int level, Node *dst, Node *src)
break;
}
// fall through
- case OSLICE:
case ODOTPTR:
case OINDEXMAP:
case OIND:
diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c
index 31bcdf8e7..da5984ceb 100644
--- a/src/cmd/gc/export.c
+++ b/src/cmd/gc/export.c
@@ -354,7 +354,7 @@ dumpexport(void)
lno = lineno;
- Bprint(bout, "\n$$ // exports\n package %s", localpkg->name);
+ Bprint(bout, "\n$$\npackage %s", localpkg->name);
if(safemode)
Bprint(bout, " safe");
Bprint(bout, "\n");
@@ -369,8 +369,7 @@ dumpexport(void)
dumpsym(l->n->sym);
}
- Bprint(bout, "\n$$ // local types\n\n$$\n"); // 6l expects this. (see ld/go.c)
-
+ Bprint(bout, "\n$$\n");
lineno = lno;
}
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
index 9cd344870..b5f8a834f 100644
--- a/src/cmd/gc/fmt.c
+++ b/src/cmd/gc/fmt.c
@@ -17,7 +17,7 @@
// Flags: "%#O": print go syntax. (automatic unless fmtmode == FDbg)
//
// %J Node* Node details
-// Flags: "%hJ" supresses things not relevant until walk.
+// Flags: "%hJ" suppresses things not relevant until walk.
//
// %V Val* Constant values
//
@@ -102,75 +102,7 @@ setfmode(unsigned long *flags)
static int
Lconv(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=hist; h!=H; 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(debug['L'] || (fp->flags&FmtLong))
- fmtprint(fp, "%s/", 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;
+ return linklinefmt(ctxt, fp);
}
static char*
@@ -702,9 +634,17 @@ typefmt(Fmt *fp, Type *t)
case TSTRUCT:
// Format the bucket struct for map[x]y as map.bucket[x]y.
// This avoids a recursive print that generates very long names.
- if(t->hmap != T) {
- t = t->hmap;
- return fmtprint(fp, "map.bucket[%T]%T", t->down, t->type);
+ if(t->map != T) {
+ if(t->map->bucket == t) {
+ return fmtprint(fp, "map.bucket[%T]%T", t->map->down, t->map->type);
+ }
+ if(t->map->hmap == t) {
+ return fmtprint(fp, "map.hdr[%T]%T", t->map->down, t->map->type);
+ }
+ if(t->map->hiter == t) {
+ return fmtprint(fp, "map.iter[%T]%T", t->map->down, t->map->type);
+ }
+ yyerror("unknown internal map type");
}
if(t->funarg) {
@@ -738,12 +678,17 @@ typefmt(Fmt *fp, Type *t)
if(!(fp->flags&FmtShort)) {
s = t->sym;
- // Take the name from the original, lest we substituted it with ~anon%d
+ // Take the name from the original, lest we substituted it with ~r%d or ~b%d.
+ // ~r%d is a (formerly) unnamed result.
if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N) {
if(t->nname->orig != N) {
s = t->nname->orig->sym;
- if(s != S && s->name[0] == '~')
- s = S;
+ if(s != S && s->name[0] == '~') {
+ if(s->name[1] == 'r') // originally an unnamed result
+ s = S;
+ else if(s->name[1] == 'b') // originally the blank identifier _
+ s = lookup("_");
+ }
} else
s = S;
}
@@ -1099,6 +1044,7 @@ static int opprec[] = {
[OEMPTY] = -1,
[OFALL] = -1,
[OFOR] = -1,
+ [OGOTO] = -1,
[OIF] = -1,
[OLABEL] = -1,
[OPROC] = -1,
@@ -1163,7 +1109,10 @@ exprfmt(Fmt *f, Node *n, int prec)
case PAUTO:
case PPARAM:
case PPARAMOUT:
- if(fmtmode == FExp && n->sym && !isblanksym(n->sym) && n->vargen > 0)
+ // _ becomes ~b%d internally; print as _ for export
+ if(fmtmode == FExp && n->sym && n->sym->name[0] == '~' && n->sym->name[1] == 'b')
+ return fmtprint(f, "_");
+ if(fmtmode == FExp && n->sym && !isblank(n) && n->vargen > 0)
return fmtprint(f, "%S·%d", n->sym, n->vargen);
}
@@ -1390,7 +1339,6 @@ exprfmt(Fmt *f, Node *n, int prec)
// Binary
case OADD:
- case OADDSTR:
case OAND:
case OANDAND:
case OANDNOT:
@@ -1415,6 +1363,14 @@ exprfmt(Fmt *f, Node *n, int prec)
exprfmt(f, n->right, nprec+1);
return 0;
+ case OADDSTR:
+ for(l=n->list; l; l=l->next) {
+ if(l != n->list)
+ fmtprint(f, " + ");
+ exprfmt(f, l->n, nprec);
+ }
+ return 0;
+
case OCMPSTR:
case OCMPIFACE:
exprfmt(f, n->left, nprec);
@@ -1572,6 +1528,9 @@ Sconv(Fmt *fp)
int r, sm;
unsigned long sf;
+ if(fp->flags&FmtLong)
+ return linksymfmt(fp);
+
s = va_arg(fp->args, Sym*);
if(s == S)
return fmtstrcpy(fp, "<S>");
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
index ada16eacc..cf630f348 100644
--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -301,6 +301,9 @@ gen(Node *n)
break;
case OLABEL:
+ if(isblanksym(n->left->sym))
+ break;
+
lab = newlab(n);
// if there are pending gotos, resolve them all to the current pc.
@@ -495,6 +498,11 @@ gen(Node *n)
case OCHECKNIL:
cgen_checknil(n->left);
+ break;
+
+ case OVARKILL:
+ gvarkill(n->left);
+ break;
}
ret:
@@ -562,8 +570,7 @@ cgen_proc(Node *n, int proc)
/*
* generate declaration.
- * nothing to do for on-stack automatics,
- * but might have to allocate heap copy
+ * have to allocate heap copy
* for escaped variables.
*/
static void
@@ -739,6 +746,8 @@ cgen_as(Node *nl, Node *nr)
if(tl == T)
return;
if(isfat(tl)) {
+ if(nl->op == ONAME)
+ gvardef(nl);
clearfat(nl);
return;
}
@@ -767,10 +776,18 @@ cgen_eface(Node *n, Node *res)
* so it's important that it is done first
*/
Node dst;
+ Node *tmp;
+
+ tmp = temp(types[tptr]);
+ cgen(n->right, tmp);
+
+ gvardef(res);
+
dst = *res;
dst.type = types[tptr];
dst.xoffset += widthptr;
- cgen(n->right, &dst);
+ cgen(tmp, &dst);
+
dst.xoffset -= widthptr;
cgen(n->left, &dst);
}
@@ -787,7 +804,7 @@ cgen_eface(Node *n, Node *res)
void
cgen_slice(Node *n, Node *res)
{
- Node src, dst, *cap, *len, *offs, *add;
+ Node src, dst, *cap, *len, *offs, *add, *base;
cap = n->list->n;
len = n->list->next->n;
@@ -795,24 +812,15 @@ cgen_slice(Node *n, Node *res)
if(n->list->next->next)
offs = n->list->next->next->n;
- // dst.len = hi [ - lo ]
- dst = *res;
- dst.xoffset += Array_nel;
- dst.type = types[simtype[TUINT]];
- cgen(len, &dst);
-
- if(n->op != OSLICESTR) {
- // dst.cap = cap [ - lo ]
- dst = *res;
- dst.xoffset += Array_cap;
- dst.type = types[simtype[TUINT]];
- cgen(cap, &dst);
- }
-
- // dst.array = src.array [ + lo *width ]
- dst = *res;
- dst.xoffset += Array_array;
- dst.type = types[TUINTPTR];
+ // evaluate base pointer first, because it is the only
+ // possibly complex expression. once that is evaluated
+ // and stored, updating the len and cap can be done
+ // without making any calls, so without doing anything that
+ // might cause preemption or garbage collection.
+ // this makes the whole slice update atomic as far as the
+ // garbage collector can see.
+
+ base = temp(types[TUINTPTR]);
if(isnil(n->left)) {
tempname(&src, n->left->type);
@@ -821,24 +829,49 @@ cgen_slice(Node *n, Node *res)
src = *n->left;
if(n->op == OSLICE || n->op == OSLICE3 || n->op == OSLICESTR)
src.xoffset += Array_array;
- src.type = types[TUINTPTR];
if(n->op == OSLICEARR || n->op == OSLICE3ARR) {
if(!isptr[n->left->type->etype])
fatal("slicearr is supposed to work on pointer: %+N\n", n);
- cgen(&src, &dst);
- cgen_checknil(&dst);
+ cgen(&src, base);
+ cgen_checknil(base);
if(offs != N) {
- add = nod(OADD, &dst, offs);
+ add = nod(OADD, base, offs);
typecheck(&add, Erv);
- cgen(add, &dst);
+ cgen(add, base);
}
} else if(offs == N) {
- cgen(&src, &dst);
+ src.type = types[tptr];
+ cgen(&src, base);
} else {
- add = nod(OADD, &src, offs);
+ src.type = types[tptr];
+ add = nod(OADDPTR, &src, offs);
typecheck(&add, Erv);
- cgen(add, &dst);
+ cgen(add, base);
+ }
+
+ // committed to the update
+ gvardef(res);
+
+ // dst.array = src.array [ + lo *width ]
+ dst = *res;
+ dst.xoffset += Array_array;
+ dst.type = types[tptr];
+
+ cgen(base, &dst);
+
+ // dst.len = hi [ - lo ]
+ dst = *res;
+ dst.xoffset += Array_nel;
+ dst.type = types[simtype[TUINT]];
+ cgen(len, &dst);
+
+ if(n->op != OSLICESTR) {
+ // dst.cap = cap [ - lo ]
+ dst = *res;
+ dst.xoffset += Array_cap;
+ dst.type = types[simtype[TUINT]];
+ cgen(cap, &dst);
}
}
@@ -935,5 +968,5 @@ temp(Type *t)
n = nod(OXXX, N, N);
tempname(n, t);
n->sym->def->used = 1;
- return n;
+ return n->orig;
}
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 562f16890..413e71069 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
#include <bio.h>
+#include <link.h>
#undef OAPPEND
@@ -31,7 +32,6 @@ enum
STRINGSZ = 200,
MAXALIGN = 7,
UINF = 100,
- HISTSZ = 10,
PRIME1 = 3,
@@ -129,6 +129,10 @@ struct Val
} u;
};
+// prevent incompatible type signatures between libgc and 8g on Plan 9
+#pragma incomplete struct Array
+
+typedef struct Array Array;
typedef struct Bvec Bvec;
typedef struct Pkg Pkg;
typedef struct Sym Sym;
@@ -190,6 +194,8 @@ struct Type
// TMAP
Type* bucket; // internal type representing a hash bucket
Type* hmap; // internal type representing a Hmap (map header object)
+ Type* hiter; // internal type representing hash iterator state
+ Type* map; // link from the above 3 internal types back to the map type.
int32 maplineno; // first use of TFORW as map key
int32 embedlineno; // first use of TFORW as embedded type
@@ -230,8 +236,10 @@ enum
EscNone,
EscReturn,
EscNever,
- EscBits = 4,
+ EscBits = 3,
EscMask = (1<<EscBits) - 1,
+ EscContentEscapes = 1<<EscBits, // value obtained by indirect of parameter escapes to some returned result
+ EscReturnBits = EscBits+1,
};
struct Node
@@ -277,6 +285,7 @@ struct Node
schar likely; // likeliness of if statement
uchar hasbreak; // has break statement
uchar needzero; // if it contains pointers, needs to be zeroed on function entry
+ uchar needctxt; // function uses context register (has closure variables)
uint esc; // EscXXX
int funcdepth;
@@ -392,6 +401,7 @@ struct Sym
int32 block; // blocknumber to catch redeclaration
int32 lastlineno; // last declaration for diagnostic
Pkg* origpkg; // original package for . import
+ LSym* lsym;
};
#define S ((Sym*)0)
@@ -420,16 +430,6 @@ struct Iter
Node* n;
};
-typedef struct Hist Hist;
-struct Hist
-{
- Hist* link;
- char* name;
- int32 line;
- int32 offset;
-};
-#define H ((Hist*)0)
-
// Node ops.
enum
{
@@ -447,11 +447,13 @@ enum
OSUB, // x - y
OOR, // x | y
OXOR, // x ^ y
+ OADDPTR, // ptr + uintptr, inserted by compiler only, used to avoid unsafe type changes during codegen
OADDSTR, // s + "foo"
OADDR, // &x
OANDAND, // b0 && b1
OAPPEND, // append
OARRAYBYTESTR, // string(bytes)
+ OARRAYBYTESTRTMP, // string(bytes) ephemeral
OARRAYRUNESTR, // string(runes)
OSTRARRAYBYTE, // []byte(s)
OSTRARRAYRUNE, // []rune(s)
@@ -506,7 +508,7 @@ enum
OKEY, // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
OPARAM, // The on-stack copy of a parameter or return value that escapes.
OLEN, // len
- OMAKE, // make, typechecking may convert to a more specfic OMAKEXXX.
+ OMAKE, // make, typechecking may convert to a more specific OMAKEXXX.
OMAKECHAN, // make(chan int)
OMAKEMAP, // make(map[string]int)
OMAKESLICE, // make([]int, 0)
@@ -528,7 +530,7 @@ enum
OPRINTN, // println
OPAREN, // (x)
OSEND, // c <- x
- OSLICE, // v[1:2], typechecking may convert to a more specfic OSLICEXXX.
+ OSLICE, // v[1:2], typechecking may convert to a more specific OSLICEXXX.
OSLICEARR, // a[1:2]
OSLICESTR, // s[1:2]
OSLICE3, // v[1:2:3], typechecking may convert to OSLICE3ARR.
@@ -583,6 +585,7 @@ enum
OCLOSUREVAR, // variable reference at beginning of closure function
OCFUNC, // reference to c function pointer (not go func value)
OCHECKNIL, // emit code to ensure pointer/interface not nil
+ OVARKILL, // variable is dead
// arch-specific registers
OREGISTER, // a register, such as AX.
@@ -724,6 +727,7 @@ struct Var
{
vlong offset;
Node* node;
+ Var* nextinnode;
int width;
char name;
char etype;
@@ -804,9 +808,6 @@ struct Magic
int ua; // output - adder
};
-typedef struct Prog Prog;
-#pragma incomplete Prog
-
struct Label
{
uchar used;
@@ -859,9 +860,6 @@ EXTERN Io pushedio;
EXTERN int32 lexlineno;
EXTERN int32 lineno;
EXTERN int32 prevlineno;
-EXTERN char* pathname;
-EXTERN Hist* hist;
-EXTERN Hist* ehist;
EXTERN char* infile;
EXTERN char* outfile;
@@ -870,6 +868,7 @@ EXTERN int nerrors;
EXTERN int nsavederrors;
EXTERN int nsyntaxerrors;
EXTERN int safemode;
+EXTERN int nolocalimports;
EXTERN char namebuf[NSYMB];
EXTERN char lexbuf[NSYMB];
EXTERN char litbuf[NSYMB];
@@ -950,7 +949,6 @@ EXTERN Node* lasttype;
EXTERN vlong maxarg;
EXTERN vlong stksize; // stack size for current frame
EXTERN vlong stkptrsize; // prefix of stack containing pointers
-EXTERN vlong stkzerosize; // prefix of stack that must be zeroed on entry
EXTERN int32 blockgen; // max block number
EXTERN int32 block; // current block number
EXTERN int hasdefer; // flag that curfn has defer statetment
@@ -959,12 +957,14 @@ EXTERN Node* curfn;
EXTERN int widthptr;
EXTERN int widthint;
+EXTERN int widthreg;
EXTERN Node* typesw;
EXTERN Node* nblank;
extern int thechar;
extern char* thestring;
+extern LinkArch* thelinkarch;
EXTERN int use_sse;
EXTERN char* hunk;
@@ -980,10 +980,17 @@ EXTERN char* flag_installsuffix;
EXTERN int flag_race;
EXTERN int flag_largemodel;
EXTERN int noescape;
+EXTERN int debuglive;
+EXTERN Link* ctxt;
EXTERN int nointerface;
EXTERN int fieldtrack_enabled;
EXTERN int precisestack_enabled;
+EXTERN int writearchive;
+
+EXTERN Biobuf bstdout;
+
+EXTERN int nacl;
/*
* y.tab.c
@@ -1002,6 +1009,18 @@ vlong rnd(vlong o, vlong r);
void typeinit(void);
/*
+ * array.c
+ */
+Array* arraynew(int32 capacity, int32 size);
+void arrayfree(Array *array);
+int32 arraylength(Array *array);
+void* arrayget(Array *array, int32 index);
+void arrayset(Array *array, int32 index, void *element);
+void arrayadd(Array *array, void *element);
+int32 arrayindexof(Array* array, void *element);
+void arraysort(Array* array, int (*cmp)(const void*, const void*));
+
+/*
* bits.c
*/
int Qconv(Fmt *fp);
@@ -1019,11 +1038,19 @@ int bset(Bits a, uint n);
* bv.c
*/
Bvec* bvalloc(int32 n);
-void bvset(Bvec *bv, int32 i);
-void bvres(Bvec *bv, int32 i);
+void bvandnot(Bvec *dst, Bvec *src1, Bvec *src2);
+int bvcmp(Bvec *bv1, Bvec *bv2);
+void bvcopy(Bvec *dst, Bvec *src);
+Bvec* bvconcat(Bvec *src1, Bvec *src2);
int bvget(Bvec *bv, int32 i);
int bvisempty(Bvec *bv);
-int bvcmp(Bvec *bv1, Bvec *bv2);
+void bvnot(Bvec *bv);
+void bvor(Bvec *dst, Bvec *src1, Bvec *src2);
+void bvand(Bvec *dst, Bvec *src1, Bvec *src2);
+void bvprint(Bvec *bv);
+void bvreset(Bvec *bv, int32 i);
+void bvresetall(Bvec *bv);
+void bvset(Bvec *bv, int32 i);
/*
* closure.c
@@ -1173,7 +1200,6 @@ char* expstring(void);
void mkpackage(char* pkgname);
void unimportfile(void);
int32 yylex(void);
-extern int windows;
extern int yylast;
extern int yyprev;
@@ -1230,17 +1256,19 @@ void mpxorfixfix(Mpint *a, Mpint *b);
void mpaddfltflt(Mpflt *a, Mpflt *b);
void mpdivfltflt(Mpflt *a, Mpflt *b);
double mpgetflt(Mpflt *a);
+double mpgetflt32(Mpflt *a);
void mpmovecflt(Mpflt *a, double c);
void mpmulfltflt(Mpflt *a, Mpflt *b);
void mpnegflt(Mpflt *a);
void mpnorm(Mpflt *a);
+void mpsetexp(Mpflt *a, int exp);
int mptestflt(Mpflt *a);
int sigfig(Mpflt *a);
/*
* obj.c
*/
-void Bputname(Biobuf *b, Sym *s);
+void Bputname(Biobuf *b, LSym *s);
int duint16(Sym *s, int off, uint16 v);
int duint32(Sym *s, int off, uint32 v);
int duint64(Sym *s, int off, uint64 v);
@@ -1248,8 +1276,9 @@ int duint8(Sym *s, int off, uint8 v);
int duintptr(Sym *s, int off, uint64 v);
int dsname(Sym *s, int off, char *dat, int ndat);
void dumpobj(void);
-void ieeedtod(uint64 *ieee, double native);
Sym* stringsym(char*, int);
+void slicebytes(Node*, char*, int);
+LSym* linksym(Sym*);
/*
* order.c
@@ -1274,6 +1303,7 @@ Sym* tracksym(Type *t);
Sym* typesymprefix(char *prefix, Type *t);
int haspointers(Type *t);
void usefield(Node*);
+Type* hiter(Type* t);
/*
* select.c
@@ -1434,32 +1464,21 @@ void walkstmt(Node **np);
void walkstmtlist(NodeList *l);
Node* conv(Node*, Type*);
int candiscard(Node*);
+Node* outervalue(Node*);
/*
- * arch-specific ggen.c/gsubr.c/gobj.c/pgen.c
+ * arch-specific ggen.c/gsubr.c/gobj.c/pgen.c/plive.c
*/
#define P ((Prog*)0)
-typedef struct Plist Plist;
-struct Plist
-{
- Node* name;
- Prog* firstpc;
- int recur;
- Plist* link;
-};
-
-EXTERN Plist* plist;
-EXTERN Plist* plast;
-
EXTERN Prog* continpc;
EXTERN Prog* breakpc;
EXTERN Prog* pc;
EXTERN Prog* firstpc;
-EXTERN Prog* retpc;
EXTERN Node* nodfp;
EXTERN int disable_checknil;
+EXTERN vlong zerosize;
int anyregalloc(void);
void betypeinit(void);
@@ -1474,59 +1493,52 @@ void cgen_checknil(Node*);
void cgen_ret(Node *n);
void clearfat(Node *n);
void compile(Node*);
-void defframe(Prog*, Bvec*);
+void defframe(Prog*);
int dgostringptr(Sym*, int off, char *str);
int dgostrlitptr(Sym*, int off, Strlit*);
int dstringptr(Sym *s, int off, char *str);
int dsymptr(Sym *s, int off, Sym *x, int xoff);
int duintxx(Sym *s, int off, uint64 v, int wid);
void dumpdata(void);
-void dumpfuncs(void);
void fixautoused(Prog*);
void gdata(Node*, Node*, int);
void gdatacomplex(Node*, Mpcplx*);
void gdatastring(Node*, Strlit*);
void ggloblnod(Node *nam);
void ggloblsym(Sym *s, int32 width, int dupok, int rodata);
+void gvardef(Node*);
+void gvarkill(Node*);
Prog* gjmp(Prog*);
void gused(Node*);
void movelarge(NodeList*);
int isfat(Type*);
+void linkarchinit(void);
+void liveness(Node*, Prog*, Sym*, Sym*);
void markautoused(Prog*);
Plist* newplist(void);
Node* nodarg(Type*, int);
void nopout(Prog*);
void patch(Prog*, Prog*);
Prog* unpatch(Prog*);
-void zfile(Biobuf *b, char *p, int n);
-void zhist(Biobuf *b, int line, vlong offset);
-void zname(Biobuf *b, Sym *s, int t);
-#pragma varargck type "A" int
#pragma varargck type "B" Mpint*
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
#pragma varargck type "E" int
#pragma varargck type "E" uint
#pragma varargck type "F" Mpflt*
#pragma varargck type "H" NodeList*
#pragma varargck type "J" Node*
-#pragma varargck type "lL" int
-#pragma varargck type "lL" uint
-#pragma varargck type "L" int
-#pragma varargck type "L" uint
+#pragma varargck type "lL" int32
+#pragma varargck type "L" int32
#pragma varargck type "N" Node*
#pragma varargck type "lN" Node*
+#pragma varargck type "O" int
#pragma varargck type "O" uint
-#pragma varargck type "P" Prog*
#pragma varargck type "Q" Bits
-#pragma varargck type "R" int
#pragma varargck type "S" Sym*
-#pragma varargck type "lS" Sym*
+#pragma varargck type "lS" LSym*
#pragma varargck type "T" Type*
#pragma varargck type "lT" Type*
#pragma varargck type "V" Val*
-#pragma varargck type "Y" char*
#pragma varargck type "Z" Strlit*
/*
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 5432eca85..2f354f723 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -557,6 +557,7 @@ caseblock:
// This is so that the stmt_list action doesn't look at
// the case tokens if the stmt_list is empty.
yylast = yychar;
+ $1->xoffset = block;
}
stmt_list
{
@@ -1730,6 +1731,7 @@ non_dcl_stmt:
{
// will be converted to OFALL
$$ = nod(OXFALL, N, N);
+ $$->xoffset = block;
}
| LBREAK onew_name
{
@@ -2138,6 +2140,10 @@ hidden_literal:
case CTFLT:
mpnegflt($$->val.u.fval);
break;
+ case CTCPLX:
+ mpnegflt(&$$->val.u.cval->real);
+ mpnegflt(&$$->val.u.cval->imag);
+ break;
default:
yyerror("bad negated constant");
}
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
index 6800884a0..cf89b0090 100644
--- a/src/cmd/gc/inl.c
+++ b/src/cmd/gc/inl.c
@@ -392,6 +392,8 @@ inlnode(Node **np)
case OCALLFUNC:
case OCALLMETH:
case OCALLINTER:
+ case OAPPEND:
+ case OCOMPLEX:
// if we just replaced arg in f(arg()) or return arg with an inlined call
// and arg returns multiple values, glue as list
if(count(n->list) == 1 && n->list->n->op == OINLCALL && count(n->list->n->rlist) > 1) {
@@ -800,6 +802,7 @@ inlvar(Node *var)
n->class = PAUTO;
n->used = 1;
n->curfn = curfn; // the calling function, not the called one
+ n->addrtaken = var->addrtaken;
// esc pass wont run if we're inlining into a iface wrapper
// luckily, we can steal the results from the target func
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 8c739391a..a50101c42 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -14,7 +14,6 @@
#define ungetc ccungetc
extern int yychar;
-int windows;
int yyprev;
int yylast;
@@ -61,7 +60,7 @@ static void
addexp(char *s)
{
int i;
-
+
for(i=0; exper[i].name != nil; i++) {
if(strcmp(exper[i].name, s) == 0) {
*exper[i].val = 1;
@@ -78,8 +77,10 @@ setexp(void)
{
char *f[20];
int i, nf;
-
- // The makefile #defines GOEXPERIMENT for us.
+
+ precisestack_enabled = 1; // on by default
+
+ // cmd/dist #defines GOEXPERIMENT for us.
nf = getfields(GOEXPERIMENT, f, nelem(f), 1, ",");
for(i=0; i<nf; i++)
addexp(f[i]);
@@ -165,6 +166,21 @@ fault(int s)
fatal("fault");
}
+#ifdef PLAN9
+void
+catcher(void *v, char *s)
+{
+ USED(v);
+
+ if(strncmp(s, "sys: trap: fault read", 21) == 0) {
+ if(nsavederrors + nerrors > 0)
+ errorexit();
+ fatal("fault");
+ }
+ noted(NDFLT);
+}
+#endif
+
void
doversion(void)
{
@@ -189,6 +205,24 @@ main(int argc, char *argv[])
signal(SIGSEGV, fault);
#endif
+#ifdef PLAN9
+ notify(catcher);
+ // Tell the FPU to handle all exceptions.
+ setfcr(FPPDBL|FPRNR);
+#endif
+ // Allow GOARCH=thestring or GOARCH=thestringsuffix,
+ // but not other values.
+ p = getgoarch();
+ if(strncmp(p, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cg with GOARCH=%s", thechar, p);
+ goarch = p;
+
+ linkarchinit();
+ ctxt = linknew(thelinkarch);
+ ctxt->diag = yyerror;
+ ctxt->bso = &bstdout;
+ Binit(&bstdout, 1, OWRITE);
+
localpkg = mkpkg(strlit(""));
localpkg->prefix = "\"\"";
@@ -229,8 +263,11 @@ main(int argc, char *argv[])
goroot = getgoroot();
goos = getgoos();
- goarch = thestring;
-
+
+ nacl = strcmp(goos, "nacl") == 0;
+ if(nacl)
+ flag_largemodel = 1;
+
setexp();
outfile = nil;
@@ -260,12 +297,16 @@ main(int argc, char *argv[])
flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
flagcount("j", "debug runtime-initialized variables", &debug['j']);
flagcount("l", "disable inlining", &debug['l']);
+ flagcount("live", "debug liveness analysis", &debuglive);
flagcount("m", "print optimization decisions", &debug['m']);
+ flagcount("nolocalimports", "reject local (relative) imports", &nolocalimports);
flagstr("o", "obj: set output file", &outfile);
flagstr("p", "path: set expected package import path", &myimportpath);
+ flagcount("pack", "write package file instead of object file", &writearchive);
flagcount("r", "debug generated wrappers", &debug['r']);
flagcount("race", "enable race detector", &flag_race);
flagcount("s", "warn about composite literals that can be simplified", &debug['s']);
+ flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
flagcount("u", "reject unsafe code", &safemode);
flagcount("v", "increase debug verbosity", &debug['v']);
flagcount("w", "debug type checking", &debug['w']);
@@ -275,6 +316,7 @@ main(int argc, char *argv[])
flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
flagparse(&argc, &argv, usage);
+ ctxt->debugasm = debug['S'];
if(argc < 1)
usage();
@@ -319,20 +361,6 @@ main(int argc, char *argv[])
sysfatal("unsupported setting GO386=%s", p);
}
- pathname = mal(1000);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
-
- if(yy_isalpha(pathname[0]) && pathname[1] == ':') {
- // On Windows.
- windows = 1;
-
- // Canonicalize path by converting \ to / (Windows accepts both).
- for(p=pathname; *p; p++)
- if(*p == '\\')
- *p = '/';
- }
-
fmtinstallgo();
betypeinit();
if(widthptr == 0)
@@ -527,12 +555,13 @@ skiptopkgdef(Biobuf *b)
return 0;
if(memcmp(p, "!<arch>\n", 8) != 0)
return 0;
- /* symbol table is first; skip it */
+ /* symbol table may be first; skip it */
sz = arsize(b, "__.GOSYMDEF");
- if(sz < 0)
- return 0;
- Bseek(b, sz, 1);
- /* package export block is second */
+ if(sz >= 0)
+ Bseek(b, sz, 1);
+ else
+ Bseek(b, 8, 0);
+ /* package export block is next */
sz = arsize(b, "__.PKGDEF");
if(sz <= 0)
return 0;
@@ -560,7 +589,7 @@ islocalname(Strlit *name)
{
if(name->len >= 1 && name->s[0] == '/')
return 1;
- if(windows && name->len >= 3 &&
+ if(ctxt->windows && name->len >= 3 &&
yy_isalpha(name->s[0]) && name->s[1] == ':' && name->s[2] == '/')
return 1;
if(name->len >= 2 && strncmp(name->s, "./", 2) == 0)
@@ -581,7 +610,7 @@ findpkg(Strlit *name)
char *q, *suffix, *suffixsep;
if(islocalname(name)) {
- if(safemode)
+ if(safemode || nolocalimports)
return 0;
// try .a before .6. important for building libraries:
// if there is an array.6 in the array.a library,
@@ -702,7 +731,7 @@ importfile(Val *f, int line)
fakeimport();
return;
}
- prefix = pathname;
+ prefix = ctxt->pathname;
if(localimport != nil)
prefix = localimport;
cleanbuf = mal(strlen(prefix) + strlen(path->s) + 2);
@@ -760,7 +789,7 @@ importfile(Val *f, int line)
yyerror("import %s: not a go object file", file);
errorexit();
}
- q = smprint("%s %s %s %s", getgoos(), thestring, getgoversion(), expstring());
+ q = smprint("%s %s %s %s", getgoos(), getgoarch(), getgoversion(), expstring());
if(strcmp(p+10, q) != 0) {
yyerror("import %s: object is [%s] expected [%s]", file, p+10, q);
errorexit();
@@ -1528,7 +1557,7 @@ getlinepragma(void)
goto out;
// try to avoid allocating file name over and over
- for(h=hist; h!=H; h=h->link) {
+ for(h=ctxt->hist; h!=nil; h=h->link) {
if(h->name != nil && strcmp(h->name, lexbuf) == 0) {
linehist(h->name, n, 0);
goto out;
@@ -2143,14 +2172,18 @@ struct
} lexn[] =
{
LANDAND, "ANDAND",
+ LANDNOT, "ANDNOT",
LASOP, "ASOP",
LBREAK, "BREAK",
LCASE, "CASE",
LCHAN, "CHAN",
LCOLAS, "COLAS",
+ LCOMM, "<-",
LCONST, "CONST",
LCONTINUE, "CONTINUE",
+ LDDD, "...",
LDEC, "DEC",
+ LDEFAULT, "DEFAULT",
LDEFER, "DEFER",
LELSE, "ELSE",
LEQ, "EQ",
@@ -2177,6 +2210,7 @@ struct
LRANGE, "RANGE",
LRETURN, "RETURN",
LRSH, "RSH",
+ LSELECT, "SELECT",
LSTRUCT, "STRUCT",
LSWITCH, "SWITCH",
LTYPE, "TYPE",
@@ -2207,6 +2241,7 @@ struct
"LASOP", "op=",
"LBREAK", "break",
"LCASE", "case",
+ "LCHAN", "chan",
"LCOLAS", ":=",
"LCONST", "const",
"LCONTINUE", "continue",
@@ -2354,7 +2389,7 @@ mkpackage(char* pkgname)
if(outfile == nil) {
p = strrchr(infile, '/');
- if(windows) {
+ if(ctxt->windows) {
q = strrchr(infile, '\\');
if(q > p)
p = q;
diff --git a/src/cmd/gc/md5.c b/src/cmd/gc/md5.c
index bbd4e298f..0051ac964 100644
--- a/src/cmd/gc/md5.c
+++ b/src/cmd/gc/md5.c
@@ -63,7 +63,7 @@ md5write(MD5 *d, uchar *p, int nn)
}
uint64
-md5sum(MD5 *d)
+md5sum(MD5 *d, uint64 *hi)
{
uchar tmp[64];
int i;
@@ -87,6 +87,8 @@ md5sum(MD5 *d)
if(d->nx != 0)
fatal("md5sum");
+ if(hi != nil)
+ *hi = d->s[2] | ((uint64)d->s[3]<<32);
return d->s[0] | ((uint64)d->s[1]<<32);
}
diff --git a/src/cmd/gc/md5.h b/src/cmd/gc/md5.h
index f153e30f2..5a60106b2 100644
--- a/src/cmd/gc/md5.h
+++ b/src/cmd/gc/md5.h
@@ -13,4 +13,4 @@ struct MD5
void md5reset(MD5*);
void md5write(MD5*, uchar*, int);
-uint64 md5sum(MD5*);
+uint64 md5sum(MD5*, uint64*);
diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c
index e25044a8b..1519caec7 100644
--- a/src/cmd/gc/mparith1.c
+++ b/src/cmd/gc/mparith1.c
@@ -65,7 +65,7 @@ mpcmpfltc(Mpflt *b, double c)
Mpflt a;
mpmovecflt(&a, c);
- return mpcmpfltflt(&a, b);
+ return mpcmpfltflt(b, &a);
}
void
@@ -416,7 +416,7 @@ mpatoflt(Mpflt *a, char *as)
if(eb) {
if(dp)
goto bad;
- a->exp += ex;
+ mpsetexp(a, a->exp+ex);
goto out;
}
@@ -427,8 +427,14 @@ mpatoflt(Mpflt *a, char *as)
mppow10flt(&b, ex-dp);
mpmulfltflt(a, &b);
} else {
- mppow10flt(&b, dp-ex);
- mpdivfltflt(a, &b);
+ // 4 approximates least_upper_bound(log2(10)).
+ if(dp-ex >= (1<<(8*sizeof(dp)-3)) || (short)(4*(dp-ex)) != 4*(dp-ex)) {
+ mpmovecflt(a, 0.0);
+ }
+ else {
+ mppow10flt(&b, dp-ex);
+ mpdivfltflt(a, &b);
+ }
}
}
@@ -573,20 +579,40 @@ Fconv(Fmt *fp)
{
char buf[500];
Mpflt *fvp, fv;
- double d;
+ double d, dexp;
+ int exp;
fvp = va_arg(fp->args, Mpflt*);
if(fp->flags & FmtSharp) {
// alternate form - decimal for error messages.
// for well in range, convert to double and use print's %g
- if(-900 < fvp->exp && fvp->exp < 900) {
+ exp = fvp->exp + sigfig(fvp)*Mpscale;
+ if(-900 < exp && exp < 900) {
d = mpgetflt(fvp);
if(d >= 0 && (fp->flags & FmtSign))
fmtprint(fp, "+");
- return fmtprint(fp, "%g", d);
+ return fmtprint(fp, "%g", d, exp, fvp);
+ }
+
+ // very out of range. compute decimal approximation by hand.
+ // decimal exponent
+ dexp = fvp->exp * 0.301029995663981195; // log_10(2)
+ exp = (int)dexp;
+ // decimal mantissa
+ fv = *fvp;
+ fv.val.neg = 0;
+ fv.exp = 0;
+ d = mpgetflt(&fv);
+ d *= pow(10, dexp-exp);
+ while(d >= 9.99995) {
+ d /= 10;
+ exp++;
}
- // TODO(rsc): for well out of range, print
- // an approximation like 1.234e1000
+ if(fvp->val.neg)
+ fmtprint(fp, "-");
+ else if(fp->flags & FmtSign)
+ fmtprint(fp, "+");
+ return fmtprint(fp, "%.5fe+%d", d, exp);
}
if(sigfig(fvp) == 0) {
diff --git a/src/cmd/gc/mparith2.c b/src/cmd/gc/mparith2.c
index 9b2f664f7..5cf98c62c 100644
--- a/src/cmd/gc/mparith2.c
+++ b/src/cmd/gc/mparith2.c
@@ -300,13 +300,21 @@ mpmulfixfix(Mpint *a, Mpint *b)
for(i=0; i<na; i++) {
x = *a1++;
for(j=0; j<Mpscale; j++) {
- if(x & 1)
+ if(x & 1) {
+ if(s.ovf) {
+ q.ovf = 1;
+ goto out;
+ }
mpaddfixfix(&q, &s, 1);
+ if(q.ovf)
+ goto out;
+ }
mplsh(&s, 1);
x >>= 1;
}
}
+out:
q.neg = a->neg ^ b->neg;
mpmovefixfix(a, &q);
if(a->ovf)
diff --git a/src/cmd/gc/mparith3.c b/src/cmd/gc/mparith3.c
index f8344c9b4..95618f1c6 100644
--- a/src/cmd/gc/mparith3.c
+++ b/src/cmd/gc/mparith3.c
@@ -23,6 +23,27 @@ sigfig(Mpflt *a)
}
/*
+ * sets the exponent.
+ * a too large exponent is an error.
+ * a too small exponent rounds the number to zero.
+ */
+void
+mpsetexp(Mpflt *a, int exp) {
+ if((short)exp != exp) {
+ if(exp > 0) {
+ yyerror("float constant is too large");
+ a->exp = 0x7fff;
+ }
+ else {
+ mpmovecflt(a, 0);
+ }
+ }
+ else {
+ a->exp = exp;
+ }
+}
+
+/*
* shifts the leading non-zero
* word of the number to Mpnorm
*/
@@ -60,7 +81,7 @@ mpnorm(Mpflt *a)
}
mpshiftfix(&a->val, s);
- a->exp -= s;
+ mpsetexp(a, a->exp-s);
}
/// implements float arihmetic
@@ -95,7 +116,7 @@ mpaddfltflt(Mpflt *a, Mpflt *b)
if(s < 0) {
// b is larger, shift a right
mpshiftfix(&a->val, s);
- a->exp -= s;
+ mpsetexp(a, a->exp-s);
mpaddfixfix(&a->val, &b->val, 0);
goto out;
}
@@ -131,7 +152,7 @@ mpmulfltflt(Mpflt *a, Mpflt *b)
}
mpmulfract(&a->val, &b->val);
- a->exp = (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1;
+ mpsetexp(a, (a->exp + b->exp) + Mpscale*Mpprec - Mpscale - 1);
mpnorm(a);
if(Mpdebug)
@@ -171,18 +192,18 @@ mpdivfltflt(Mpflt *a, Mpflt *b)
// divide
mpdivfract(&a->val, &c.val);
- a->exp = (a->exp-c.exp) - Mpscale*(Mpprec-1) + 1;
+ mpsetexp(a, (a->exp-c.exp) - Mpscale*(Mpprec-1) + 1);
mpnorm(a);
if(Mpdebug)
print(" = %F\n\n", a);
}
-double
-mpgetflt(Mpflt *a)
+static double
+mpgetfltN(Mpflt *a, int prec, int bias)
{
- int s, i, e;
- uvlong v, vm;
+ int s, i, e, minexp;
+ uvlong v;
double f;
if(a->val.ovf && nsavederrors+nerrors == 0)
@@ -199,59 +220,69 @@ mpgetflt(Mpflt *a)
while((a->val.a[Mpnorm-1] & Mpsign) == 0) {
mpshiftfix(&a->val, 1);
- a->exp -= 1;
+ mpsetexp(a, a->exp-1); // can set 'a' to zero
+ s = sigfig(a);
+ if(s == 0)
+ return 0;
}
- // the magic numbers (64, 63, 53, 10, -1074) are
- // IEEE specific. this should be done machine
- // independently or in the 6g half of the compiler
-
- // pick up the mantissa and a rounding bit in a uvlong
- s = 53+1;
+ // pick up the mantissa, a rounding bit, and a tie-breaking bit in a uvlong
+ s = prec+2;
v = 0;
for(i=Mpnorm-1; s>=Mpscale; i--) {
v = (v<<Mpscale) | a->val.a[i];
s -= Mpscale;
}
- vm = v;
- if(s > 0)
- vm = (vm<<s) | (a->val.a[i]>>(Mpscale-s));
-
- // continue with 64 more bits
- s += 64;
- for(; s>=Mpscale; i--) {
- v = (v<<Mpscale) | a->val.a[i];
- s -= Mpscale;
- }
- if(s > 0)
+ if(s > 0) {
v = (v<<s) | (a->val.a[i]>>(Mpscale-s));
+ if((a->val.a[i]&((1<<(Mpscale-s))-1)) != 0)
+ v |= 1;
+ i--;
+ }
+ for(; i >= 0; i--) {
+ if(a->val.a[i] != 0)
+ v |= 1;
+ }
// gradual underflow
- e = Mpnorm*Mpscale + a->exp - 53;
- if(e < -1074) {
- s = -e - 1074;
- if(s > 54)
- s = 54;
- v |= vm & ((1ULL<<s) - 1);
- vm >>= s;
- e = -1074;
+ e = Mpnorm*Mpscale + a->exp - prec;
+ minexp = bias+1-prec+1;
+ if(e < minexp) {
+ s = minexp - e;
+ if(s > prec+1)
+ s = prec+1;
+ if((v & ((1<<s)-1)) != 0)
+ v |= 1<<s;
+ v >>= s;
+ e = minexp;
}
+
+ // round to even
+ v |= (v&4)>>2;
+ v += v&1;
+ v >>= 2;
-//print("vm=%.16llux v=%.16llux\n", vm, v);
- // round toward even
- if(v != 0 || (vm&2ULL) != 0)
- vm = (vm>>1) + (vm&1ULL);
- else
- vm >>= 1;
-
- f = (double)(vm);
+ f = (double)(v);
f = ldexp(f, e);
if(a->val.neg)
f = -f;
+
return f;
}
+double
+mpgetflt(Mpflt *a)
+{
+ return mpgetfltN(a, 53, -1023);
+}
+
+double
+mpgetflt32(Mpflt *a)
+{
+ return mpgetfltN(a, 24, -127);
+}
+
void
mpmovecflt(Mpflt *a, double c)
{
diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c
index 4cad08924..4eeb03aa8 100644
--- a/src/cmd/gc/obj.c
+++ b/src/cmd/gc/obj.c
@@ -10,13 +10,28 @@
* architecture-independent object file output
*/
-static void outhist(Biobuf *b);
static void dumpglobls(void);
+enum
+{
+ ArhdrSize = 60
+};
+
+static void
+formathdr(char *arhdr, char *name, vlong size)
+{
+ snprint(arhdr, ArhdrSize, "%-16s%-12d%-6d%-6d%-8o%-10lld`",
+ name, 0, 0, 0, 0644, size);
+ arhdr[ArhdrSize-1] = '\n'; // overwrite \0 written by snprint
+}
+
void
dumpobj(void)
{
NodeList *externs, *tmp;
+ char arhdr[ArhdrSize];
+ vlong startobj, size;
+ Sym *zero;
bout = Bopen(outfile, OWRITE);
if(bout == nil) {
@@ -25,13 +40,34 @@ dumpobj(void)
errorexit();
}
- Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring());
- Bprint(bout, " exports automatically generated from\n");
- Bprint(bout, " %s in package \"%s\"\n", curio.infile, localpkg->name);
+ startobj = 0;
+ if(writearchive) {
+ Bwrite(bout, "!<arch>\n", 8);
+ memset(arhdr, 0, sizeof arhdr);
+ Bwrite(bout, arhdr, sizeof arhdr);
+ startobj = Boffset(bout);
+ }
+ Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring());
dumpexport();
- Bprint(bout, "\n!\n");
+
+ if(writearchive) {
+ Bflush(bout);
+ size = Boffset(bout) - startobj;
+ if(size&1)
+ Bputc(bout, 0);
+ Bseek(bout, startobj - ArhdrSize, 0);
+ formathdr(arhdr, "__.PKGDEF", size);
+ Bwrite(bout, arhdr, ArhdrSize);
+ Bflush(bout);
+
+ Bseek(bout, startobj + size + (size&1), 0);
+ memset(arhdr, 0, ArhdrSize);
+ Bwrite(bout, arhdr, ArhdrSize);
+ startobj = Boffset(bout);
+ Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring());
+ }
- outhist(bout);
+ Bprint(bout, "\n!\n");
externs = nil;
if(externdcl != nil)
@@ -47,9 +83,22 @@ dumpobj(void)
dumpglobls();
externdcl = tmp;
- dumpdata();
- dumpfuncs();
+ zero = pkglookup("zerovalue", runtimepkg);
+ ggloblsym(zero, zerosize, 1, 1);
+ dumpdata();
+ writeobj(ctxt, bout);
+
+ if(writearchive) {
+ Bflush(bout);
+ size = Boffset(bout) - startobj;
+ if(size&1)
+ Bputc(bout, 0);
+ Bseek(bout, startobj - ArhdrSize, 0);
+ snprint(namebuf, sizeof namebuf, "_go_.%c", thechar);
+ formathdr(arhdr, namebuf, size);
+ Bwrite(bout, arhdr, ArhdrSize);
+ }
Bterm(bout);
}
@@ -75,184 +124,50 @@ dumpglobls(void)
ggloblnod(n);
}
-
+
for(l=funcsyms; l; l=l->next) {
n = l->n;
dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
ggloblsym(n->sym, widthptr, 1, 1);
}
+
+ // Do not reprocess funcsyms on next dumpglobls call.
+ funcsyms = nil;
}
void
-Bputname(Biobuf *b, Sym *s)
+Bputname(Biobuf *b, LSym *s)
{
- Bprint(b, "%s", s->pkg->prefix);
- BPUTC(b, '.');
Bwrite(b, s->name, strlen(s->name)+1);
}
-static void
-outzfile(Biobuf *b, char *p)
-{
- char *q, *q2;
-
- while(p) {
- q = utfrune(p, '/');
- if(windows) {
- q2 = utfrune(p, '\\');
- if(q2 && (!q || q2 < q))
- q = q2;
- }
- if(!q) {
- zfile(b, p, strlen(p));
- return;
- }
- if(q > p)
- zfile(b, p, q-p);
- p = q + 1;
- }
-}
-
-#define isdelim(c) (c == '/' || c == '\\')
-
-static void
-outwinname(Biobuf *b, Hist *h, char *ds, char *p)
+LSym*
+linksym(Sym *s)
{
- if(isdelim(p[0])) {
- // full rooted name
- zfile(b, ds, 3); // leading "c:/"
- outzfile(b, p+1);
- } else {
- // relative name
- if(h->offset >= 0 && pathname && pathname[1] == ':') {
- if(tolowerrune(ds[0]) == tolowerrune(pathname[0])) {
- // using current drive
- zfile(b, pathname, 3); // leading "c:/"
- outzfile(b, pathname+3);
- } else {
- // using drive other then current,
- // we don't have any simple way to
- // determine current working directory
- // there, therefore will output name as is
- zfile(b, ds, 2); // leading "c:"
- }
- }
- outzfile(b, p);
+ char *p;
+
+ if(s == nil)
+ return nil;
+ if(s->lsym != nil)
+ return s->lsym;
+ if(isblanksym(s))
+ s->lsym = linklookup(ctxt, "_", 0);
+ else {
+ p = smprint("%s.%s", s->pkg->prefix, s->name);
+ s->lsym = linklookup(ctxt, p, 0);
+ free(p);
}
+ return s->lsym;
}
-static void
-outhist(Biobuf *b)
-{
- Hist *h;
- char *p, ds[] = {'c', ':', '/', 0};
- char *tofree;
- int n;
- static int first = 1;
- static char *goroot, *goroot_final;
-
- if(first) {
- // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
- first = 0;
- goroot = getenv("GOROOT");
- goroot_final = getenv("GOROOT_FINAL");
- if(goroot == nil)
- goroot = "";
- if(goroot_final == nil)
- goroot_final = goroot;
- if(strcmp(goroot, goroot_final) == 0) {
- goroot = nil;
- goroot_final = nil;
- }
- }
-
- tofree = nil;
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- if(p) {
- if(goroot != nil) {
- n = strlen(goroot);
- if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
- tofree = smprint("%s%s", goroot_final, p+n);
- p = tofree;
- }
- }
- if(windows) {
- // if windows variable is set, then, we know already,
- // pathname is started with windows drive specifier
- // and all '\' were replaced with '/' (see lex.c)
- if(isdelim(p[0]) && isdelim(p[1])) {
- // file name has network name in it,
- // like \\server\share\dir\file.go
- zfile(b, "//", 2); // leading "//"
- outzfile(b, p+2);
- } else if(p[1] == ':') {
- // file name has drive letter in it
- ds[0] = p[0];
- outwinname(b, h, ds, p+2);
- } else {
- // no drive letter in file name
- outwinname(b, h, pathname, p);
- }
- } else {
- if(p[0] == '/') {
- // full rooted name, like /home/rsc/dir/file.go
- zfile(b, "/", 1); // leading "/"
- outzfile(b, p+1);
- } else {
- // relative name, like dir/file.go
- if(h->offset >= 0 && pathname && pathname[0] == '/') {
- zfile(b, "/", 1); // leading "/"
- outzfile(b, pathname+1);
- }
- outzfile(b, p);
- }
- }
- }
- zhist(b, h->line, h->offset);
- if(tofree) {
- free(tofree);
- tofree = nil;
- }
- }
-}
-
-void
-ieeedtod(uint64 *ieee, double native)
+int
+duintxx(Sym *s, int off, uint64 v, int wid)
{
- double fr, ho, f;
- int exp;
- uint32 h, l;
- uint64 bits;
-
- if(native < 0) {
- ieeedtod(ieee, -native);
- *ieee |= 1ULL<<63;
- return;
- }
- if(native == 0) {
- *ieee = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldn't use fp constants here */
- fr = modf(fr*f, &ho);
- h = ho;
- h &= 0xfffffL;
- f = 65536L;
- fr = modf(fr*f, &ho);
- l = ho;
- l <<= 16;
- l |= (int32)(fr*f);
- bits = ((uint64)h<<32) | l;
- if(exp < -1021) {
- // gradual underflow
- bits |= 1LL<<52;
- bits >>= -1021 - exp;
- exp = -1022;
- }
- bits |= (uint64)(exp+1022L) << 52;
- *ieee = bits;
+ // Update symbol data directly instead of generating a
+ // DATA instruction that liblink will have to interpret later.
+ // This reduces compilation time and memory usage.
+ off = rnd(off, wid);
+ return setuintxx(ctxt, linksym(s), off, v, wid);
}
int
@@ -338,3 +253,31 @@ stringsym(char *s, int len)
return sym;
}
+
+void
+slicebytes(Node *nam, char *s, int len)
+{
+ int off, n, m;
+ static int gen;
+ Sym *sym;
+
+ snprint(namebuf, sizeof(namebuf), ".gobytes.%d", ++gen);
+ sym = pkglookup(namebuf, localpkg);
+ sym->def = newname(sym);
+
+ off = 0;
+ for(n=0; n<len; n+=m) {
+ m = 8;
+ if(m > len-n)
+ m = len-n;
+ off = dsname(sym, off, s+n, m);
+ }
+ ggloblsym(sym, off, 0, 0);
+
+ if(nam->op != ONAME)
+ fatal("slicebytes %N", nam);
+ off = nam->xoffset;
+ off = dsymptr(nam->sym, off, sym, 0);
+ off = duintxx(nam->sym, off, len, widthint);
+ duintxx(nam->sym, off, len, widthint);
+}
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c
index 7552510e9..30dbc7dac 100644
--- a/src/cmd/gc/order.c
+++ b/src/cmd/gc/order.c
@@ -5,79 +5,343 @@
// Rewrite tree to use separate statements to enforce
// order of evaluation. Makes walk easier, because it
// can (after this runs) reorder at will within an expression.
+//
+// Rewrite x op= y into x = x op y.
+//
+// Introduce temporaries as needed by runtime routines.
+// For example, the map runtime routines take the map key
+// by reference, so make sure all map keys are addressable
+// by copying them to temporaries as needed.
+// The same is true for channel operations.
+//
+// Arrange that map index expressions only appear in direct
+// assignments x = m[k] or m[k] = x, never in larger expressions.
+//
+// Arrange that receive expressions only appear in direct assignments
+// x = <-c or as standalone statements <-c, never in larger expressions.
+
+// TODO(rsc): The temporary introduction during multiple assignments
+// should be moved into this file, so that the temporaries can be cleaned
+// and so that conversions implicit in the OAS2FUNC and OAS2RECV
+// nodes can be made explicit and then have their temporaries cleaned.
+
+// TODO(rsc): Goto and multilevel break/continue can jump over
+// inserted VARKILL annotations. Work out a way to handle these.
+// The current implementation is safe, in that it will execute correctly.
+// But it won't reuse temporaries as aggressively as it might, and
+// it can result in unnecessary zeroing of those variables in the function
+// prologue.
#include <u.h>
#include <libc.h>
#include "go.h"
-static void orderstmt(Node*, NodeList**);
-static void orderstmtlist(NodeList*, NodeList**);
+// Order holds state during the ordering process.
+typedef struct Order Order;
+struct Order
+{
+ NodeList *out; // list of generated statements
+ NodeList *temp; // head of stack of temporary variables
+ NodeList *free; // free list of NodeList* structs (for use in temp)
+};
+
+static void orderstmt(Node*, Order*);
+static void orderstmtlist(NodeList*, Order*);
static void orderblock(NodeList **l);
-static void orderexpr(Node**, NodeList**);
-static void orderexprlist(NodeList*, NodeList**);
+static void orderexpr(Node**, Order*);
+static void orderexprinplace(Node**, Order*);
+static void orderexprlist(NodeList*, Order*);
+static void orderexprlistinplace(NodeList*, Order*);
+// Order rewrites fn->nbody to apply the ordering constraints
+// described in the comment at the top of the file.
void
order(Node *fn)
{
orderblock(&fn->nbody);
}
+// Ordertemp allocates a new temporary with the given type,
+// pushes it onto the temp stack, and returns it.
+// If clear is true, ordertemp emits code to zero the temporary.
+static Node*
+ordertemp(Type *t, Order *order, int clear)
+{
+ Node *var, *a;
+ NodeList *l;
+
+ var = temp(t);
+ if(clear) {
+ a = nod(OAS, var, N);
+ typecheck(&a, Etop);
+ order->out = list(order->out, a);
+ }
+ if((l = order->free) == nil)
+ l = mal(sizeof *l);
+ order->free = l->next;
+ l->next = order->temp;
+ l->n = var;
+ order->temp = l;
+ return var;
+}
+
+// Ordercopyexpr behaves like ordertemp but also emits
+// code to initialize the temporary to the value n.
+//
+// The clear argument is provided for use when the evaluation
+// of tmp = n turns into a function call that is passed a pointer
+// to the temporary as the output space. If the call blocks before
+// tmp has been written, the garbage collector will still treat the
+// temporary as live, so we must zero it before entering that call.
+// Today, this only happens for channel receive operations.
+// (The other candidate would be map access, but map access
+// returns a pointer to the result data instead of taking a pointer
+// to be filled in.)
+static Node*
+ordercopyexpr(Node *n, Type *t, Order *order, int clear)
+{
+ Node *a, *var;
+
+ var = ordertemp(t, order, clear);
+ a = nod(OAS, var, n);
+ typecheck(&a, Etop);
+ order->out = list(order->out, a);
+ return var;
+}
+
+// Ordercheapexpr returns a cheap version of n.
+// The definition of cheap is that n is a variable or constant.
+// If not, ordercheapexpr allocates a new tmp, emits tmp = n,
+// and then returns tmp.
+static Node*
+ordercheapexpr(Node *n, Order *order)
+{
+ switch(n->op) {
+ case ONAME:
+ case OLITERAL:
+ return n;
+ }
+ return ordercopyexpr(n, n->type, order, 0);
+}
+
+// Ordersafeexpr returns a safe version of n.
+// The definition of safe is that n can appear multiple times
+// without violating the semantics of the original program,
+// and that assigning to the safe version has the same effect
+// as assigning to the original n.
+//
+// The intended use is to apply to x when rewriting x += y into x = x + y.
+static Node*
+ordersafeexpr(Node *n, Order *order)
+{
+ Node *l, *r, *a;
+
+ switch(n->op) {
+ default:
+ fatal("ordersafeexpr %O", n->op);
+
+ case ONAME:
+ case OLITERAL:
+ return n;
+
+ case ODOT:
+ l = ordersafeexpr(n->left, order);
+ if(l == n->left)
+ return n;
+ a = nod(OXXX, N, N);
+ *a = *n;
+ a->orig = a;
+ a->left = l;
+ typecheck(&a, Erv);
+ return a;
+
+ case ODOTPTR:
+ case OIND:
+ l = ordercheapexpr(n->left, order);
+ if(l == n->left)
+ return n;
+ a = nod(OXXX, N, N);
+ *a = *n;
+ a->orig = a;
+ a->left = l;
+ typecheck(&a, Erv);
+ return a;
+
+ case OINDEX:
+ case OINDEXMAP:
+ if(isfixedarray(n->left->type))
+ l = ordersafeexpr(n->left, order);
+ else
+ l = ordercheapexpr(n->left, order);
+ r = ordercheapexpr(n->right, order);
+ if(l == n->left && r == n->right)
+ return n;
+ a = nod(OXXX, N, N);
+ *a = *n;
+ a->orig = a;
+ a->left = l;
+ a->right = r;
+ typecheck(&a, Erv);
+ return a;
+ }
+}
+
+// Istemp reports whether n is a temporary variable.
+static int
+istemp(Node *n)
+{
+ if(n->op != ONAME)
+ return 0;
+ return strncmp(n->sym->name, "autotmp_", 8) == 0;
+}
+
+// Isaddrokay reports whether it is okay to pass n's address to runtime routines.
+// Taking the address of a variable makes the liveness and optimization analyses
+// lose track of where the variable's lifetime ends. To avoid hurting the analyses
+// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
+// because we emit explicit VARKILL instructions marking the end of those
+// temporaries' lifetimes.
+static int
+isaddrokay(Node *n)
+{
+ return islvalue(n) && (n->op != ONAME || n->class == PEXTERN || istemp(n));
+}
+
+// Orderaddrtemp ensures that *np is okay to pass by address to runtime routines.
+// If the original argument *np is not okay, orderaddrtemp creates a tmp, emits
+// tmp = *np, and then sets *np to the tmp variable.
static void
-orderstmtlist(NodeList *l, NodeList **out)
+orderaddrtemp(Node **np, Order *order)
+{
+ Node *n;
+
+ n = *np;
+ if(isaddrokay(n))
+ return;
+ *np = ordercopyexpr(n, n->type, order, 0);
+}
+
+// Marktemp returns the top of the temporary variable stack.
+static NodeList*
+marktemp(Order *order)
+{
+ return order->temp;
+}
+
+// Poptemp pops temporaries off the stack until reaching the mark,
+// which must have been returned by marktemp.
+static void
+poptemp(NodeList *mark, Order *order)
+{
+ NodeList *l;
+
+ while((l = order->temp) != mark) {
+ order->temp = l->next;
+ l->next = order->free;
+ order->free = l;
+ }
+}
+
+// Cleantempnopop emits to *out VARKILL instructions for each temporary
+// above the mark on the temporary stack, but it does not pop them
+// from the stack.
+static void
+cleantempnopop(NodeList *mark, Order *order, NodeList **out)
+{
+ NodeList *l;
+ Node *kill;
+
+ for(l=order->temp; l != mark; l=l->next) {
+ kill = nod(OVARKILL, l->n, N);
+ typecheck(&kill, Etop);
+ *out = list(*out, kill);
+ }
+}
+
+// Cleantemp emits VARKILL instructions for each temporary above the
+// mark on the temporary stack and removes them from the stack.
+static void
+cleantemp(NodeList *top, Order *order)
+{
+ cleantempnopop(top, order, &order->out);
+ poptemp(top, order);
+}
+
+// Orderstmtlist orders each of the statements in the list.
+static void
+orderstmtlist(NodeList *l, Order *order)
{
for(; l; l=l->next)
- orderstmt(l->n, out);
+ orderstmt(l->n, order);
}
-// Order the block of statements *l onto a new list,
-// and then replace *l with that list.
+// Orderblock orders the block of statements *l onto a new list,
+// and then replaces *l with that list.
static void
orderblock(NodeList **l)
{
- NodeList *out;
+ Order order;
+ NodeList *mark;
- out = nil;
- orderstmtlist(*l, &out);
- *l = out;
+ memset(&order, 0, sizeof order);
+ mark = marktemp(&order);
+ orderstmtlist(*l, &order);
+ cleantemp(mark, &order);
+ *l = order.out;
}
-// Order the side effects in *np and leave them as
-// the init list of the final *np.
+// Orderexprinplace orders the side effects in *np and
+// leaves them as the init list of the final *np.
static void
-orderexprinplace(Node **np)
+orderexprinplace(Node **np, Order *outer)
{
Node *n;
- NodeList *out;
+ NodeList **lp;
+ Order order;
n = *np;
- out = nil;
- orderexpr(&n, &out);
- addinit(&n, out);
+ memset(&order, 0, sizeof order);
+ orderexpr(&n, &order);
+ addinit(&n, order.out);
+
+ // insert new temporaries from order
+ // at head of outer list.
+ lp = &order.temp;
+ while(*lp != nil)
+ lp = &(*lp)->next;
+ *lp = outer->temp;
+ outer->temp = order.temp;
+
*np = n;
}
-// Like orderblock, but applied to a single statement.
+// Orderstmtinplace orders the side effects of the single statement *np
+// and replaces it with the resulting statement list.
static void
orderstmtinplace(Node **np)
{
Node *n;
- NodeList *out;
-
+ Order order;
+ NodeList *mark;
+
n = *np;
- out = nil;
- orderstmt(n, &out);
- *np = liststmt(out);
+ memset(&order, 0, sizeof order);
+ mark = marktemp(&order);
+ orderstmt(n, &order);
+ cleantemp(mark, &order);
+ *np = liststmt(order.out);
}
-// Move n's init list to *out.
+// Orderinit moves n's init list to order->out.
static void
-orderinit(Node *n, NodeList **out)
+orderinit(Node *n, Order *order)
{
- orderstmtlist(n->ninit, out);
+ orderstmtlist(n->ninit, order);
n->ninit = nil;
}
-// Is the list l actually just f() for a multi-value function?
+// Ismulticall reports whether the list l is f() for a multi-value function.
+// Such an f() could appear as the lone argument to a multi-arg function.
static int
ismulticall(NodeList *l)
{
@@ -102,10 +366,10 @@ ismulticall(NodeList *l)
return n->left->type->outtuple > 1;
}
-// n is a multi-value function call. Add t1, t2, .. = n to out
-// and return the list t1, t2, ...
+// Copyret emits t1, t2, ... = n, where n is a function call,
+// and then returns the list t1, t2, ....
static NodeList*
-copyret(Node *n, NodeList **out)
+copyret(Node *n, Order *order)
{
Type *t;
Node *tmp, *as;
@@ -127,86 +391,224 @@ copyret(Node *n, NodeList **out)
as->list = l1;
as->rlist = list1(n);
typecheck(&as, Etop);
- orderstmt(as, out);
+ orderstmt(as, order);
return l2;
}
+// Ordercallargs orders the list of call arguments *l.
static void
-ordercallargs(NodeList **l, NodeList **out)
+ordercallargs(NodeList **l, Order *order)
{
if(ismulticall(*l)) {
// return f() where f() is multiple values.
- *l = copyret((*l)->n, out);
+ *l = copyret((*l)->n, order);
} else {
- orderexprlist(*l, out);
+ orderexprlist(*l, order);
}
}
+// Ordercall orders the call expression n.
+// n->op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
static void
-ordercall(Node *n, NodeList **out)
+ordercall(Node *n, Order *order)
{
- orderexpr(&n->left, out);
- ordercallargs(&n->list, out);
+ orderexpr(&n->left, order);
+ orderexpr(&n->right, order); // ODDDARG temp
+ ordercallargs(&n->list, order);
}
+// Ordermapassign appends n to order->out, introducing temporaries
+// to make sure that all map assignments have the form m[k] = x,
+// where x is adressable.
+// (Orderexpr has already been called on n, so we know k is addressable.)
+//
+// If n is m[k] = x where x is not addressable, the rewrite is:
+// tmp = x
+// m[k] = tmp
+//
+// If n is the multiple assignment form ..., m[k], ... = ..., the rewrite is
+// t1 = m
+// t2 = k
+// ...., t3, ... = x
+// t1[t2] = t3
+//
+// The temporaries t1, t2 are needed in case the ... being assigned
+// contain m or k. They are usually unnecessary, but in the unnecessary
+// cases they are also typically registerizable, so not much harm done.
+// And this only applies to the multiple-assignment form.
+// We could do a more precise analysis if needed, like in walk.c.
static void
-orderstmt(Node *n, NodeList **out)
+ordermapassign(Node *n, Order *order)
{
- int lno;
+ Node *m, *a;
NodeList *l;
- Node *r;
+ NodeList *post;
+
+ switch(n->op) {
+ default:
+ fatal("ordermapassign %O", n->op);
+
+ case OAS:
+ order->out = list(order->out, n);
+ if(n->left->op == OINDEXMAP && !isaddrokay(n->right)) {
+ m = n->left;
+ n->left = ordertemp(m->type, order, 0);
+ a = nod(OAS, m, n->left);
+ typecheck(&a, Etop);
+ order->out = list(order->out, a);
+ }
+ break;
+
+ case OAS2:
+ case OAS2DOTTYPE:
+ case OAS2MAPR:
+ case OAS2FUNC:
+ post = nil;
+ for(l=n->list; l != nil; l=l->next) {
+ if(l->n->op == OINDEXMAP) {
+ m = l->n;
+ if(!istemp(m->left))
+ m->left = ordercopyexpr(m->left, m->left->type, order, 0);
+ if(!istemp(m->right))
+ m->right = ordercopyexpr(m->right, m->right->type, order, 0);
+ l->n = ordertemp(m->type, order, 0);
+ a = nod(OAS, m, l->n);
+ typecheck(&a, Etop);
+ post = list(post, a);
+ }
+ }
+ order->out = list(order->out, n);
+ order->out = concat(order->out, post);
+ break;
+ }
+}
+
+// Orderstmt orders the statement n, appending to order->out.
+// Temporaries created during the statement are cleaned
+// up using VARKILL instructions as possible.
+static void
+orderstmt(Node *n, Order *order)
+{
+ int lno;
+ NodeList *l, *t, *t1;
+ Node *r, *tmp1, *tmp2, **np;
+ Type *ch;
if(n == N)
return;
lno = setlineno(n);
- orderinit(n, out);
+ orderinit(n, order);
switch(n->op) {
default:
fatal("orderstmt %O", n->op);
+ case OVARKILL:
+ order->out = list(order->out, n);
+ break;
+
+ case OAS:
case OAS2:
case OAS2DOTTYPE:
- case OAS2MAPR:
- case OAS:
- case OASOP:
case OCLOSE:
case OCOPY:
- case ODELETE:
- case OPANIC:
case OPRINT:
case OPRINTN:
case ORECOVER:
case ORECV:
- case OSEND:
- orderexpr(&n->left, out);
- orderexpr(&n->right, out);
- orderexprlist(n->list, out);
- orderexprlist(n->rlist, out);
- *out = list(*out, n);
+ t = marktemp(order);
+ orderexpr(&n->left, order);
+ orderexpr(&n->right, order);
+ orderexprlist(n->list, order);
+ orderexprlist(n->rlist, order);
+ switch(n->op) {
+ case OAS:
+ case OAS2:
+ case OAS2DOTTYPE:
+ ordermapassign(n, order);
+ break;
+ default:
+ order->out = list(order->out, n);
+ break;
+ }
+ cleantemp(t, order);
break;
-
+
+ case OASOP:
+ // Special: rewrite l op= r into l = l op r.
+ // This simplies quite a few operations;
+ // most important is that it lets us separate
+ // out map read from map write when l is
+ // a map index expression.
+ t = marktemp(order);
+ orderexpr(&n->left, order);
+ n->left = ordersafeexpr(n->left, order);
+ tmp1 = treecopy(n->left);
+ if(tmp1->op == OINDEXMAP)
+ tmp1->etype = 0; // now an rvalue not an lvalue
+ tmp1 = ordercopyexpr(tmp1, n->left->type, order, 0);
+ n->right = nod(n->etype, tmp1, n->right);
+ typecheck(&n->right, Erv);
+ orderexpr(&n->right, order);
+ n->etype = 0;
+ n->op = OAS;
+ ordermapassign(n, order);
+ cleantemp(t, order);
+ break;
+
+ case OAS2MAPR:
+ // Special: make sure key is addressable,
+ // and make sure OINDEXMAP is not copied out.
+ t = marktemp(order);
+ orderexprlist(n->list, order);
+ r = n->rlist->n;
+ orderexpr(&r->left, order);
+ orderexpr(&r->right, order);
+ // See case OINDEXMAP below.
+ if(r->right->op == OARRAYBYTESTR)
+ r->right->op = OARRAYBYTESTRTMP;
+ orderaddrtemp(&r->right, order);
+ ordermapassign(n, order);
+ cleantemp(t, order);
+ break;
+
case OAS2FUNC:
// Special: avoid copy of func call n->rlist->n.
- orderexprlist(n->list, out);
- ordercall(n->rlist->n, out);
- *out = list(*out, n);
+ t = marktemp(order);
+ orderexprlist(n->list, order);
+ ordercall(n->rlist->n, order);
+ ordermapassign(n, order);
+ cleantemp(t, order);
break;
case OAS2RECV:
// Special: avoid copy of receive.
- orderexprlist(n->list, out);
- orderexpr(&n->rlist->n->left, out); // arg to recv
- *out = list(*out, n);
+ // Use temporary variables to hold result,
+ // so that chanrecv can take address of temporary.
+ t = marktemp(order);
+ orderexprlist(n->list, order);
+ orderexpr(&n->rlist->n->left, order); // arg to recv
+ ch = n->rlist->n->left->type;
+ tmp1 = ordertemp(ch->type, order, haspointers(ch->type));
+ tmp2 = ordertemp(types[TBOOL], order, 0);
+ order->out = list(order->out, n);
+ r = nod(OAS, n->list->n, tmp1);
+ typecheck(&r, Etop);
+ ordermapassign(r, order);
+ r = nod(OAS, n->list->next->n, tmp2);
+ typecheck(&r, Etop);
+ ordermapassign(r, order);
+ n->list = list(list1(tmp1), tmp2);
+ cleantemp(t, order);
break;
case OBLOCK:
case OEMPTY:
// Special: does not save n onto out.
- orderstmtlist(n->list, out);
+ orderstmtlist(n->list, order);
break;
case OBREAK:
@@ -215,109 +617,329 @@ orderstmt(Node *n, NodeList **out)
case ODCLCONST:
case ODCLTYPE:
case OFALL:
- case_OFALL:
+ case OXFALL:
case OGOTO:
case OLABEL:
case ORETJMP:
// Special: n->left is not an expression; save as is.
- *out = list(*out, n);
+ order->out = list(order->out, n);
break;
case OCALLFUNC:
case OCALLINTER:
case OCALLMETH:
// Special: handle call arguments.
- ordercall(n, out);
- *out = list(*out, n);
+ t = marktemp(order);
+ ordercall(n, order);
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
case ODEFER:
case OPROC:
// Special: order arguments to inner call but not call itself.
- ordercall(n->left, out);
- *out = list(*out, n);
+ t = marktemp(order);
+ switch(n->left->op) {
+ case ODELETE:
+ // Delete will take the address of the key.
+ // Copy key into new temp and do not clean it
+ // (it persists beyond the statement).
+ orderexprlist(n->left->list, order);
+ t1 = marktemp(order);
+ np = &n->left->list->next->n; // map key
+ *np = ordercopyexpr(*np, (*np)->type, order, 0);
+ poptemp(t1, order);
+ break;
+ default:
+ ordercall(n->left, order);
+ break;
+ }
+ order->out = list(order->out, n);
+ cleantemp(t, order);
+ break;
+
+ case ODELETE:
+ t = marktemp(order);
+ orderexpr(&n->list->n, order);
+ orderexpr(&n->list->next->n, order);
+ orderaddrtemp(&n->list->next->n, order); // map key
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
case OFOR:
- orderexprinplace(&n->ntest);
- orderstmtinplace(&n->nincr);
+ // Clean temporaries from condition evaluation at
+ // beginning of loop body and after for statement.
+ t = marktemp(order);
+ orderexprinplace(&n->ntest, order);
+ l = nil;
+ cleantempnopop(t, order, &l);
+ n->nbody = concat(l, n->nbody);
orderblock(&n->nbody);
- *out = list(*out, n);
+ orderstmtinplace(&n->nincr);
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
case OIF:
- orderexprinplace(&n->ntest);
+ // Clean temporaries from condition at
+ // beginning of both branches.
+ t = marktemp(order);
+ orderexprinplace(&n->ntest, order);
+ l = nil;
+ cleantempnopop(t, order, &l);
+ n->nbody = concat(l, n->nbody);
+ l = nil;
+ cleantempnopop(t, order, &l);
+ n->nelse = concat(l, n->nelse);
+ poptemp(t, order);
orderblock(&n->nbody);
orderblock(&n->nelse);
- *out = list(*out, n);
+ order->out = list(order->out, n);
+ break;
+
+ case OPANIC:
+ // Special: argument will be converted to interface using convT2E
+ // so make sure it is an addressable temporary.
+ t = marktemp(order);
+ orderexpr(&n->left, order);
+ if(!isinter(n->left->type))
+ orderaddrtemp(&n->left, order);
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
case ORANGE:
- orderexpr(&n->right, out);
+ // n->right is the expression being ranged over.
+ // order it, and then make a copy if we need one.
+ // We almost always do, to ensure that we don't
+ // see any value changes made during the loop.
+ // Usually the copy is cheap (e.g., array pointer, chan, slice, string are all tiny).
+ // The exception is ranging over an array value (not a slice, not a pointer to array),
+ // which must make a copy to avoid seeing updates made during
+ // the range body. Ranging over an array value is uncommon though.
+ t = marktemp(order);
+ orderexpr(&n->right, order);
+ switch(n->type->etype) {
+ default:
+ fatal("orderstmt range %T", n->type);
+ case TARRAY:
+ if(count(n->list) < 2 || isblank(n->list->next->n)) {
+ // for i := range x will only use x once, to compute len(x).
+ // No need to copy it.
+ break;
+ }
+ // fall through
+ case TCHAN:
+ case TSTRING:
+ // chan, string, slice, array ranges use value multiple times.
+ // make copy.
+ r = n->right;
+ if(r->type->etype == TSTRING && r->type != types[TSTRING]) {
+ r = nod(OCONV, r, N);
+ r->type = types[TSTRING];
+ typecheck(&r, Erv);
+ }
+ n->right = ordercopyexpr(r, r->type, order, 0);
+ break;
+ case TMAP:
+ // copy the map value in case it is a map literal.
+ // TODO(rsc): Make tmp = literal expressions reuse tmp.
+ // For maps tmp is just one word so it hardly matters.
+ r = n->right;
+ n->right = ordercopyexpr(r, r->type, order, 0);
+ // n->alloc is the temp for the iterator.
+ n->alloc = ordertemp(types[TUINT8], order, 1);
+ break;
+ }
for(l=n->list; l; l=l->next)
- orderexprinplace(&l->n);
+ orderexprinplace(&l->n, order);
orderblock(&n->nbody);
- *out = list(*out, n);
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
case ORETURN:
- ordercallargs(&n->list, out);
- *out = list(*out, n);
+ ordercallargs(&n->list, order);
+ order->out = list(order->out, n);
break;
case OSELECT:
+ // Special: clean case temporaries in each block entry.
+ // Select must enter one of its blocks, so there is no
+ // need for a cleaning at the end.
+ t = marktemp(order);
for(l=n->list; l; l=l->next) {
if(l->n->op != OXCASE)
fatal("order select case %O", l->n->op);
r = l->n->left;
- if(r == nil)
- continue;
- switch(r->op) {
- case OSELRECV:
- case OSELRECV2:
- orderexprinplace(&r->left);
- orderexprinplace(&r->ntest);
- orderexpr(&r->right->left, &l->n->ninit);
- break;
- case OSEND:
- orderexpr(&r->left, &l->n->ninit);
- orderexpr(&r->right, &l->n->ninit);
- break;
+ setlineno(l->n);
+ // Append any new body prologue to ninit.
+ // The next loop will insert ninit into nbody.
+ if(l->n->ninit != nil)
+ fatal("order select ninit");
+ if(r != nil) {
+ switch(r->op) {
+ default:
+ yyerror("unknown op in select %O", r->op);
+ dump("select case", r);
+ break;
+
+ case OSELRECV:
+ case OSELRECV2:
+ // If this is case x := <-ch or case x, y := <-ch, the case has
+ // the ODCL nodes to declare x and y. We want to delay that
+ // declaration (and possible allocation) until inside the case body.
+ // Delete the ODCL nodes here and recreate them inside the body below.
+ if(r->colas) {
+ t = r->ninit;
+ if(t != nil && t->n->op == ODCL && t->n->left == r->left)
+ t = t->next;
+ if(t != nil && t->n->op == ODCL && t->n->left == r->ntest)
+ t = t->next;
+ if(t == nil)
+ r->ninit = nil;
+ }
+ if(r->ninit != nil) {
+ yyerror("ninit on select recv");
+ dumplist("ninit", r->ninit);
+ }
+ // case x = <-c
+ // case x, ok = <-c
+ // r->left is x, r->ntest is ok, r->right is ORECV, r->right->left is c.
+ // r->left == N means 'case <-c'.
+ // c is always evaluated; x and ok are only evaluated when assigned.
+ orderexpr(&r->right->left, order);
+
+ // Introduce temporary for receive and move actual copy into case body.
+ // avoids problems with target being addressed, as usual.
+ // NOTE: If we wanted to be clever, we could arrange for just one
+ // temporary per distinct type, sharing the temp among all receives
+ // with that temp. Similarly one ok bool could be shared among all
+ // the x,ok receives. Not worth doing until there's a clear need.
+ if(r->left != N && isblank(r->left))
+ r->left = N;
+ if(r->left != N) {
+ // use channel element type for temporary to avoid conversions,
+ // such as in case interfacevalue = <-intchan.
+ // the conversion happens in the OAS instead.
+ tmp1 = r->left;
+ if(r->colas) {
+ tmp2 = nod(ODCL, tmp1, N);
+ typecheck(&tmp2, Etop);
+ l->n->ninit = list(l->n->ninit, tmp2);
+ }
+ r->left = ordertemp(r->right->left->type->type, order, haspointers(r->right->left->type->type));
+ tmp2 = nod(OAS, tmp1, r->left);
+ typecheck(&tmp2, Etop);
+ l->n->ninit = list(l->n->ninit, tmp2);
+ }
+ if(r->ntest != N && isblank(r->ntest))
+ r->ntest = N;
+ if(r->ntest != N) {
+ tmp1 = r->ntest;
+ if(r->colas) {
+ tmp2 = nod(ODCL, tmp1, N);
+ typecheck(&tmp2, Etop);
+ l->n->ninit = list(l->n->ninit, tmp2);
+ }
+ r->ntest = ordertemp(tmp1->type, order, 0);
+ tmp2 = nod(OAS, tmp1, r->ntest);
+ typecheck(&tmp2, Etop);
+ l->n->ninit = list(l->n->ninit, tmp2);
+ }
+ orderblock(&l->n->ninit);
+ break;
+
+ case OSEND:
+ if(r->ninit != nil) {
+ yyerror("ninit on select send");
+ dumplist("ninit", r->ninit);
+ }
+ // case c <- x
+ // r->left is c, r->right is x, both are always evaluated.
+ orderexpr(&r->left, order);
+ if(!istemp(r->left))
+ r->left = ordercopyexpr(r->left, r->left->type, order, 0);
+ orderexpr(&r->right, order);
+ if(!istemp(r->right))
+ r->right = ordercopyexpr(r->right, r->right->type, order, 0);
+ break;
+ }
}
+ orderblock(&l->n->nbody);
}
- *out = list(*out, n);
+ // Now that we have accumulated all the temporaries, clean them.
+ // Also insert any ninit queued during the previous loop.
+ // (The temporary cleaning must follow that ninit work.)
+ for(l=n->list; l; l=l->next) {
+ cleantempnopop(t, order, &l->n->ninit);
+ l->n->nbody = concat(l->n->ninit, l->n->nbody);
+ l->n->ninit = nil;
+ }
+ order->out = list(order->out, n);
+ poptemp(t, order);
+ break;
+
+ case OSEND:
+ // Special: value being sent is passed as a pointer; make it addressable.
+ t = marktemp(order);
+ orderexpr(&n->left, order);
+ orderexpr(&n->right, order);
+ orderaddrtemp(&n->right, order);
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
case OSWITCH:
- orderexpr(&n->ntest, out);
+ // TODO(rsc): Clean temporaries more aggressively.
+ // Note that because walkswitch will rewrite some of the
+ // switch into a binary search, this is not as easy as it looks.
+ // (If we ran that code here we could invoke orderstmt on
+ // the if-else chain instead.)
+ // For now just clean all the temporaries at the end.
+ // In practice that's fine.
+ t = marktemp(order);
+ orderexpr(&n->ntest, order);
for(l=n->list; l; l=l->next) {
if(l->n->op != OXCASE)
fatal("order switch case %O", l->n->op);
- orderexpr(&l->n->left, &l->n->ninit);
+ orderexprlistinplace(l->n->list, order);
+ orderblock(&l->n->nbody);
}
- *out = list(*out, n);
+ order->out = list(order->out, n);
+ cleantemp(t, order);
break;
-
- case OXFALL:
- yyerror("fallthrough statement out of place");
- n->op = OFALL;
- goto case_OFALL;
}
lineno = lno;
}
+// Orderexprlist orders the expression list l into order.
+static void
+orderexprlist(NodeList *l, Order *order)
+{
+ for(; l; l=l->next)
+ orderexpr(&l->n, order);
+}
+
+// Orderexprlist orders the expression list l but saves
+// the side effects on the individual expression ninit lists.
static void
-orderexprlist(NodeList *l, NodeList **out)
+orderexprlistinplace(NodeList *l, Order *order)
{
for(; l; l=l->next)
- orderexpr(&l->n, out);
+ orderexprinplace(&l->n, order);
}
+// Orderexpr orders a single expression, appending side
+// effects to order->out as needed.
static void
-orderexpr(Node **np, NodeList **out)
+orderexpr(Node **np, Order *order)
{
Node *n;
+ NodeList *mark, *l;
+ Type *t;
int lno;
n = *np;
@@ -325,31 +947,113 @@ orderexpr(Node **np, NodeList **out)
return;
lno = setlineno(n);
- orderinit(n, out);
+ orderinit(n, order);
switch(n->op) {
default:
- orderexpr(&n->left, out);
- orderexpr(&n->right, out);
- orderexprlist(n->list, out);
- orderexprlist(n->rlist, out);
+ orderexpr(&n->left, order);
+ orderexpr(&n->right, order);
+ orderexprlist(n->list, order);
+ orderexprlist(n->rlist, order);
+ break;
+
+ case OADDSTR:
+ // Addition of strings turns into a function call.
+ // Allocate a temporary to hold the strings.
+ // Fewer than 5 strings use direct runtime helpers.
+ orderexprlist(n->list, order);
+ if(count(n->list) > 5) {
+ t = typ(TARRAY);
+ t->bound = count(n->list);
+ t->type = types[TSTRING];
+ n->alloc = ordertemp(t, order, 0);
+ }
+ break;
+
+ case OINDEXMAP:
+ // key must be addressable
+ orderexpr(&n->left, order);
+ orderexpr(&n->right, order);
+
+ // For x = m[string(k)] where k is []byte, the allocation of
+ // backing bytes for the string can be avoided by reusing
+ // the []byte backing array. This is a special case that it
+ // would be nice to handle more generally, but because
+ // there are no []byte-keyed maps, this specific case comes
+ // up in important cases in practice. See issue 3512.
+ // Nothing can change the []byte we are not copying before
+ // the map index, because the map access is going to
+ // be forced to happen immediately following this
+ // conversion (by the ordercopyexpr a few lines below).
+ if(n->etype == 0 && n->right->op == OARRAYBYTESTR)
+ n->right->op = OARRAYBYTESTRTMP;
+
+ orderaddrtemp(&n->right, order);
+ if(n->etype == 0) {
+ // use of value (not being assigned);
+ // make copy in temporary.
+ n = ordercopyexpr(n, n->type, order, 0);
+ }
+ break;
+
+ case OCONVIFACE:
+ // concrete type (not interface) argument must be addressable
+ // temporary to pass to runtime.
+ orderexpr(&n->left, order);
+ if(!isinter(n->left->type))
+ orderaddrtemp(&n->left, order);
break;
case OANDAND:
case OOROR:
- orderexpr(&n->left, out);
- orderexprinplace(&n->right);
+ mark = marktemp(order);
+ orderexpr(&n->left, order);
+ // Clean temporaries from first branch at beginning of second.
+ // Leave them on the stack so that they can be killed in the outer
+ // context in case the short circuit is taken.
+ l = nil;
+ cleantempnopop(mark, order, &l);
+ n->right->ninit = concat(l, n->right->ninit);
+ orderexprinplace(&n->right, order);
break;
case OCALLFUNC:
case OCALLMETH:
case OCALLINTER:
- ordercall(n, out);
- n = copyexpr(n, n->type, out);
+ case OAPPEND:
+ case OCOMPLEX:
+ ordercall(n, order);
+ n = ordercopyexpr(n, n->type, order, 0);
+ break;
+
+ case OCLOSURE:
+ if(n->noescape && n->cvars != nil)
+ n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type
+ break;
+
+ case OARRAYLIT:
+ case OCALLPART:
+ orderexpr(&n->left, order);
+ orderexpr(&n->right, order);
+ orderexprlist(n->list, order);
+ orderexprlist(n->rlist, order);
+ if(n->noescape)
+ n->alloc = ordertemp(types[TUINT8], order, 0); // walk will fill in correct type
+ break;
+
+ case ODDDARG:
+ if(n->noescape) {
+ // The ddd argument does not live beyond the call it is created for.
+ // Allocate a temporary that will be cleaned up when this statement
+ // completes. We could be more aggressive and try to arrange for it
+ // to be cleaned up when the call completes.
+ n->alloc = ordertemp(n->type->type, order, 0);
+ }
break;
case ORECV:
- n = copyexpr(n, n->type, out);
+ orderexpr(&n->left, order);
+ n = ordercopyexpr(n, n->type, order, 1);
break;
}
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
index 2850af6bb..40620c3da 100644
--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -8,30 +8,159 @@
#include <u.h>
#include <libc.h>
+#include "md5.h"
#include "gg.h"
#include "opt.h"
#include "../../pkg/runtime/funcdata.h"
-enum { BitsPerPointer = 2 };
-
static void allocauto(Prog* p);
-static void dumpgcargs(Node*, Sym*);
-static Bvec* dumpgclocals(Node*, Sym*);
+
+static Sym*
+makefuncdatasym(char *namefmt, int64 funcdatakind)
+{
+ Node nod;
+ Node *pnod;
+ Sym *sym;
+ static int32 nsym;
+
+ snprint(namebuf, sizeof(namebuf), namefmt, nsym++);
+ sym = lookup(namebuf);
+ pnod = newname(sym);
+ pnod->class = PEXTERN;
+ nodconst(&nod, types[TINT32], funcdatakind);
+ gins(AFUNCDATA, &nod, pnod);
+ return sym;
+}
+
+// gvardef inserts a VARDEF for n into the instruction stream.
+// VARDEF is an annotation for the liveness analysis, marking a place
+// where a complete initialization (definition) of a variable begins.
+// Since the liveness analysis can see initialization of single-word
+// variables quite easy, gvardef is usually only called for multi-word
+// or 'fat' variables, those satisfying isfat(n->type).
+// However, gvardef is also called when a non-fat variable is initialized
+// via a block move; the only time this happens is when you have
+// return f()
+// for a function with multiple return values exactly matching the return
+// types of the current function.
+//
+// A 'VARDEF x' annotation in the instruction stream tells the liveness
+// analysis to behave as though the variable x is being initialized at that
+// point in the instruction stream. The VARDEF must appear before the
+// actual (multi-instruction) initialization, and it must also appear after
+// any uses of the previous value, if any. For example, if compiling:
+//
+// x = x[1:]
+//
+// it is important to generate code like:
+//
+// base, len, cap = pieces of x[1:]
+// VARDEF x
+// x = {base, len, cap}
+//
+// If instead the generated code looked like:
+//
+// VARDEF x
+// base, len, cap = pieces of x[1:]
+// x = {base, len, cap}
+//
+// then the liveness analysis would decide the previous value of x was
+// unnecessary even though it is about to be used by the x[1:] computation.
+// Similarly, if the generated code looked like:
+//
+// base, len, cap = pieces of x[1:]
+// x = {base, len, cap}
+// VARDEF x
+//
+// then the liveness analysis will not preserve the new value of x, because
+// the VARDEF appears to have "overwritten" it.
+//
+// VARDEF is a bit of a kludge to work around the fact that the instruction
+// stream is working on single-word values but the liveness analysis
+// wants to work on individual variables, which might be multi-word
+// aggregates. It might make sense at some point to look into letting
+// the liveness analysis work on single-word values as well, although
+// there are complications around interface values, slices, and strings,
+// all of which cannot be treated as individual words.
+//
+// VARKILL is the opposite of VARDEF: it marks a value as no longer needed,
+// even if its address has been taken. That is, a VARKILL annotation asserts
+// that its argument is certainly dead, for use when the liveness analysis
+// would not otherwise be able to deduce that fact.
+
+static void
+gvardefx(Node *n, int as)
+{
+ if(n == N)
+ fatal("gvardef nil");
+ if(n->op != ONAME) {
+ yyerror("gvardef %#O; %N", n->op, n);
+ return;
+ }
+ switch(n->class) {
+ case PAUTO:
+ case PPARAM:
+ case PPARAMOUT:
+ gins(as, N, n);
+ }
+}
+
+void
+gvardef(Node *n)
+{
+ gvardefx(n, AVARDEF);
+}
+
+void
+gvarkill(Node *n)
+{
+ gvardefx(n, AVARKILL);
+}
+
+static void
+removevardef(Prog *firstp)
+{
+ Prog *p;
+
+ for(p = firstp; p != P; p = p->link) {
+ while(p->link != P && (p->link->as == AVARDEF || p->link->as == AVARKILL))
+ p->link = p->link->link;
+ if(p->to.type == D_BRANCH)
+ while(p->to.u.branch != P && (p->to.u.branch->as == AVARDEF || p->to.u.branch->as == AVARKILL))
+ p->to.u.branch = p->to.u.branch->link;
+ }
+}
+
+static void
+gcsymdup(Sym *s)
+{
+ LSym *ls;
+ uint64 lo, hi;
+
+ ls = linksym(s);
+ if(ls->nr > 0)
+ fatal("cannot rosymdup %s with relocations", ls->name);
+ MD5 d;
+ md5reset(&d);
+ md5write(&d, ls->p, ls->np);
+ lo = md5sum(&d, &hi);
+ ls->name = smprint("gclocals·%016llux%016llux", lo, hi);
+ ls->dupok = 1;
+}
void
compile(Node *fn)
{
- Bvec *bv;
Plist *pl;
- Node nod1, *n, *gcargsnod, *gclocalsnod;
- Prog *ptxt, *p, *p1;
+ Node nod1, *n;
+ Prog *ptxt, *p;
int32 lno;
Type *t;
Iter save;
vlong oldstksize;
NodeList *l;
- Sym *gcargssym, *gclocalssym;
- static int ngcargs, ngclocals;
+ Sym *gcargs;
+ Sym *gclocals;
if(newproc == N) {
newproc = sysfunc("newproc");
@@ -45,7 +174,7 @@ compile(Node *fn)
lno = setlineno(fn);
if(fn->nbody == nil) {
- if(pure_go || memcmp(fn->nname->sym->name, "init·", 6) == 0)
+ if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0)
yyerror("missing function body", fn);
goto ret;
}
@@ -88,7 +217,7 @@ compile(Node *fn)
breakpc = P;
pl = newplist();
- pl->name = curfn->nname;
+ pl->name = linksym(curfn->nname->sym);
setlineno(curfn);
@@ -98,6 +227,8 @@ compile(Node *fn)
ptxt->TEXTFLAG |= DUPOK;
if(fn->wrapper)
ptxt->TEXTFLAG |= WRAPPER;
+ if(fn->needctxt)
+ ptxt->TEXTFLAG |= NEEDCTXT;
// Clumsy but important.
// See test/recover.go for test cases and src/pkg/reflect/value.go
@@ -111,21 +242,8 @@ compile(Node *fn)
ginit();
- snprint(namebuf, sizeof namebuf, "gcargs·%d", ngcargs++);
- gcargssym = lookup(namebuf);
- gcargsnod = newname(gcargssym);
- gcargsnod->class = PEXTERN;
-
- nodconst(&nod1, types[TINT32], FUNCDATA_GCArgs);
- gins(AFUNCDATA, &nod1, gcargsnod);
-
- snprint(namebuf, sizeof(namebuf), "gclocals·%d", ngclocals++);
- gclocalssym = lookup(namebuf);
- gclocalsnod = newname(gclocalssym);
- gclocalsnod->class = PEXTERN;
-
- nodconst(&nod1, types[TINT32], FUNCDATA_GCLocals);
- gins(AFUNCDATA, &nod1, gclocalsnod);
+ gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps);
+ gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
for(t=curfn->paramfld; t; t=t->down)
gtrack(tracksym(t->type));
@@ -140,20 +258,12 @@ compile(Node *fn)
case PPARAMOUT:
nodconst(&nod1, types[TUINTPTR], l->n->type->width);
p = gins(ATYPE, l->n, &nod1);
- p->from.gotype = ngotype(l->n);
+ p->from.gotype = linksym(ngotype(l->n));
break;
}
}
genlist(curfn->enter);
-
- retpc = nil;
- if(hasdefer || curfn->exit) {
- p1 = gjmp(nil);
- retpc = gjmp(nil);
- patch(p1, pc);
- }
-
genlist(curfn->nbody);
gclean();
checklabels();
@@ -165,13 +275,15 @@ compile(Node *fn)
if(curfn->type->outtuple != 0)
ginscall(throwreturn, 0);
- if(retpc)
- patch(retpc, pc);
ginit();
- if(hasdefer)
- ginscall(deferreturn, 0);
- if(curfn->exit)
- genlist(curfn->exit);
+ // TODO: Determine when the final cgen_ret can be omitted. Perhaps always?
+ cgen_ret(nil);
+ if(hasdefer) {
+ // deferreturn pretends to have one uintptr argument.
+ // Reserve space for it so stack scanner is happy.
+ if(maxarg < widthptr)
+ maxarg = widthptr;
+ }
gclean();
if(nerrors != 0)
goto ret;
@@ -179,6 +291,7 @@ compile(Node *fn)
pc->as = ARET; // overwrite AEND
pc->lineno = lineno;
+ fixjmp(ptxt);
if(!debug['N'] || debug['R'] || debug['P']) {
regopt(ptxt);
nilopt(ptxt);
@@ -190,6 +303,7 @@ compile(Node *fn)
if(0)
print("allocauto: %lld to %lld\n", oldstksize, (vlong)stksize);
+ USED(oldstksize);
setlineno(curfn);
if((int64)stksize+maxarg > (1ULL<<31)) {
@@ -198,184 +312,21 @@ compile(Node *fn)
}
// Emit garbage collection symbols.
- dumpgcargs(fn, gcargssym);
- bv = dumpgclocals(curfn, gclocalssym);
+ liveness(curfn, ptxt, gcargs, gclocals);
+ gcsymdup(gcargs);
+ gcsymdup(gclocals);
- defframe(ptxt, bv);
- free(bv);
+ defframe(ptxt);
if(0)
frame(0);
+ // Remove leftover instrumentation from the instruction stream.
+ removevardef(ptxt);
ret:
lineno = lno;
}
-static void
-walktype1(Type *t, vlong *xoffset, Bvec *bv)
-{
- vlong fieldoffset, i, o;
- Type *t1;
-
- if(t->align > 0 && (*xoffset % t->align) != 0)
- fatal("walktype1: invalid initial alignment, %T", t);
-
- switch(t->etype) {
- case TINT8:
- case TUINT8:
- case TINT16:
- case TUINT16:
- case TINT32:
- case TUINT32:
- case TINT64:
- case TUINT64:
- case TINT:
- case TUINT:
- case TUINTPTR:
- case TBOOL:
- case TFLOAT32:
- case TFLOAT64:
- case TCOMPLEX64:
- case TCOMPLEX128:
- *xoffset += t->width;
- break;
-
- case TPTR32:
- case TPTR64:
- case TUNSAFEPTR:
- case TFUNC:
- case TCHAN:
- case TMAP:
- if(*xoffset % widthptr != 0)
- fatal("walktype1: invalid alignment, %T", t);
- bvset(bv, (*xoffset / widthptr) * BitsPerPointer);
- *xoffset += t->width;
- break;
-
- case TSTRING:
- // struct { byte *str; intgo len; }
- if(*xoffset % widthptr != 0)
- fatal("walktype1: invalid alignment, %T", t);
- bvset(bv, (*xoffset / widthptr) * BitsPerPointer);
- *xoffset += t->width;
- break;
-
- case TINTER:
- // struct { Itab* tab; union { void* ptr, uintptr val } data; }
- // or, when isnilinter(t)==true:
- // struct { Type* type; union { void* ptr, uintptr val } data; }
- if(*xoffset % widthptr != 0)
- fatal("walktype1: invalid alignment, %T", t);
- bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1);
- if(isnilinter(t))
- bvset(bv, ((*xoffset / widthptr) * BitsPerPointer));
- *xoffset += t->width;
- break;
-
- case TARRAY:
- // The value of t->bound is -1 for slices types and >0 for
- // for fixed array types. All other values are invalid.
- if(t->bound < -1)
- fatal("walktype1: invalid bound, %T", t);
- if(isslice(t)) {
- // struct { byte* array; uintgo len; uintgo cap; }
- if(*xoffset % widthptr != 0)
- fatal("walktype1: invalid TARRAY alignment, %T", t);
- bvset(bv, (*xoffset / widthptr) * BitsPerPointer);
- *xoffset += t->width;
- } else if(!haspointers(t->type))
- *xoffset += t->width;
- else
- for(i = 0; i < t->bound; ++i)
- walktype1(t->type, xoffset, bv);
- break;
-
- case TSTRUCT:
- o = 0;
- for(t1 = t->type; t1 != T; t1 = t1->down) {
- fieldoffset = t1->width;
- *xoffset += fieldoffset - o;
- walktype1(t1->type, xoffset, bv);
- o = fieldoffset + t1->type->width;
- }
- *xoffset += t->width - o;
- break;
-
- default:
- fatal("walktype1: unexpected type, %T", t);
- }
-}
-
-static void
-walktype(Type *type, Bvec *bv)
-{
- vlong xoffset;
-
- // Start the walk at offset 0. The correct offset will be
- // filled in by the first type encountered during the walk.
- xoffset = 0;
- walktype1(type, &xoffset, bv);
-}
-
-// Compute a bit vector to describe the pointer-containing locations
-// in the in and out argument list and dump the bitvector length and
-// data to the provided symbol.
-static void
-dumpgcargs(Node *fn, Sym *sym)
-{
- Type *thistype, *inargtype, *outargtype;
- Bvec *bv;
- int32 i;
- int off;
-
- thistype = getthisx(fn->type);
- inargtype = getinargx(fn->type);
- outargtype = getoutargx(fn->type);
- bv = bvalloc((fn->type->argwid / widthptr) * BitsPerPointer);
- if(thistype != nil)
- walktype(thistype, bv);
- if(inargtype != nil)
- walktype(inargtype, bv);
- if(outargtype != nil)
- walktype(outargtype, bv);
- off = duint32(sym, 0, bv->n);
- for(i = 0; i < bv->n; i += 32)
- off = duint32(sym, off, bv->b[i/32]);
- free(bv);
- ggloblsym(sym, off, 0, 1);
-}
-
-// Compute a bit vector to describe the pointer-containing locations
-// in local variables and dump the bitvector length and data out to
-// the provided symbol. Return the vector for use and freeing by caller.
-static Bvec*
-dumpgclocals(Node* fn, Sym *sym)
-{
- Bvec *bv;
- NodeList *ll;
- Node *node;
- vlong xoffset;
- int32 i;
- int off;
-
- bv = bvalloc((stkptrsize / widthptr) * BitsPerPointer);
- for(ll = fn->dcl; ll != nil; ll = ll->next) {
- node = ll->n;
- if(node->class == PAUTO && node->op == ONAME) {
- if(haspointers(node->type)) {
- xoffset = node->xoffset + stkptrsize;
- walktype1(node->type, &xoffset, bv);
- }
- }
- }
- off = duint32(sym, 0, bv->n);
- for(i = 0; i < bv->n; i += 32) {
- off = duint32(sym, off, bv->b[i/32]);
- }
- ggloblsym(sym, off, 0, 1);
- return bv;
-}
-
// Sort the list of stack variables. Autos after anything else,
// within autos, unused after used, within used, things with
// pointers first, zeroed things first, and then decreasing size.
@@ -415,7 +366,8 @@ cmpstackvar(Node *a, Node *b)
return +1;
if(a->type->width > b->type->width)
return -1;
- return 0;
+
+ return strcmp(a->sym->name, b->sym->name);
}
// TODO(lvd) find out where the PAUTO/OLITERAL nodes come from.
@@ -428,7 +380,6 @@ allocauto(Prog* ptxt)
stksize = 0;
stkptrsize = 0;
- stkzerosize = 0;
if(curfn->dcl == nil)
return;
@@ -440,13 +391,6 @@ allocauto(Prog* ptxt)
markautoused(ptxt);
- if(precisestack_enabled) {
- // TODO: Remove when liveness analysis sets needzero instead.
- for(ll=curfn->dcl; ll != nil; ll=ll->next)
- if(ll->n->class == PAUTO)
- ll->n->needzero = 1; // ll->n->addrtaken;
- }
-
listsort(&curfn->dcl, cmpstackvar);
// Unused autos are at the end, chop 'em off.
@@ -480,11 +424,8 @@ allocauto(Prog* ptxt)
fatal("bad width");
stksize += w;
stksize = rnd(stksize, n->type->align);
- if(haspointers(n->type)) {
+ if(haspointers(n->type))
stkptrsize = stksize;
- if(n->needzero)
- stkzerosize = stksize;
- }
if(thechar == '5')
stksize = rnd(stksize, widthptr);
if(stksize >= (1ULL<<31)) {
@@ -493,9 +434,8 @@ allocauto(Prog* ptxt)
}
n->stkdelta = -stksize - n->xoffset;
}
- stksize = rnd(stksize, widthptr);
- stkptrsize = rnd(stkptrsize, widthptr);
- stkzerosize = rnd(stkzerosize, widthptr);
+ stksize = rnd(stksize, widthreg);
+ stkptrsize = rnd(stkptrsize, widthreg);
fixautoused(ptxt);
@@ -538,12 +478,12 @@ cgen_checknil(Node *n)
if(disable_checknil)
return;
- // Ideally we wouldn't see any TUINTPTR here, but we do.
- if(n->type == T || (!isptr[n->type->etype] && n->type->etype != TUINTPTR && n->type->etype != TUNSAFEPTR)) {
+ // Ideally we wouldn't see any integer types here, but we do.
+ if(n->type == T || (!isptr[n->type->etype] && !isint[n->type->etype] && n->type->etype != TUNSAFEPTR)) {
dump("checknil", n);
fatal("bad checknil");
}
- if((thechar == '5' && n->op != OREGISTER) || !n->addable) {
+ if((thechar == '5' && n->op != OREGISTER) || !n->addable || n->op == OLITERAL) {
regalloc(&reg, types[tptr], n);
cgen(n, &reg);
gins(ACHECKNIL, &reg, N);
diff --git a/src/cmd/gc/plive.c b/src/cmd/gc/plive.c
new file mode 100644
index 000000000..eb8901733
--- /dev/null
+++ b/src/cmd/gc/plive.c
@@ -0,0 +1,1985 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Garbage collector liveness bitmap generation.
+
+// The command line flag -live causes this code to print debug information.
+// The levels are:
+//
+// -live (aka -live=1): print liveness lists as code warnings at safe points
+// -live=2: print an assembly listing with liveness annotations
+// -live=3: print information during each computation phase (much chattier)
+//
+// Each level includes the earlier output as well.
+
+#include <u.h>
+#include <libc.h>
+#include "gg.h"
+#include "opt.h"
+#include "../../pkg/runtime/funcdata.h"
+
+enum { BitsPerPointer = 2 };
+
+enum {
+ UNVISITED = 0,
+ VISITED = 1,
+};
+
+// An ordinary basic block.
+//
+// Instructions are threaded together in a doubly-linked list. To iterate in
+// program order follow the link pointer from the first node and stop after the
+// last node has been visited
+//
+// for(p = bb->first;; p = p->link) {
+// ...
+// if(p == bb->last)
+// break;
+// }
+//
+// To iterate in reverse program order by following the opt pointer from the
+// last node
+//
+// for(p = bb->last; p != nil; p = p->opt) {
+// ...
+// }
+typedef struct BasicBlock BasicBlock;
+struct BasicBlock {
+ // An array of preceding blocks. If the length of this array is 0 the
+ // block is probably the start block of the CFG.
+ Array *pred;
+
+ // An array out succeeding blocks. If the length of this array is zero,
+ // the block probably ends in a return instruction.
+ Array *succ;
+
+ // First instruction in the block. When part of a fully initialized
+ // control flow graph, the opt member will be nil.
+ Prog *first;
+
+ // Last instruction in the basic block.
+ Prog *last;
+
+ // The reverse post order number. This value is initialized to -1 and
+ // will be replaced by a non-negative value when the CFG is constructed.
+ // After CFG construction, if rpo is -1 this block is unreachable.
+ int rpo;
+
+ // State to denote whether the block has been visited during a
+ // traversal.
+ int mark;
+
+ // For use during livenessepilogue.
+ int lastbitmapindex;
+};
+
+// A collection of global state used by liveness analysis.
+typedef struct Liveness Liveness;
+struct Liveness {
+ // A pointer to the node corresponding to the function being analyzed.
+ Node *fn;
+
+ // A linked list of instructions for this function.
+ Prog *ptxt;
+
+ // A list of arguments and local variables in this function.
+ Array *vars;
+
+ // A list of basic blocks that are overlayed on the instruction list.
+ // The blocks are roughly in the same order as the instructions
+ // in the function (first block has TEXT instruction, and so on).
+ Array *cfg;
+
+ // Summary sets of block effects.
+ // The Bvec** is indexed by bb->rpo to yield a single Bvec*.
+ // That bit vector is indexed by variable number (same as lv->vars).
+ //
+ // Computed during livenessprologue using only the content of
+ // individual blocks:
+ //
+ // uevar: upward exposed variables (used before set in block)
+ // varkill: killed variables (set in block)
+ // avarinit: addrtaken variables set or used (proof of initialization)
+ //
+ // Computed during livenesssolve using control flow information:
+ //
+ // livein: variables live at block entry
+ // liveout: variables live at block exit
+ // avarinitany: addrtaken variables possibly initialized at block exit
+ // (initialized in block or at exit from any predecessor block)
+ // avarinitall: addrtaken variables certainly initialized at block exit
+ // (initialized in block or at exit from all predecessor blocks)
+ Bvec **uevar;
+ Bvec **varkill;
+ Bvec **livein;
+ Bvec **liveout;
+ Bvec **avarinit;
+ Bvec **avarinitany;
+ Bvec **avarinitall;
+
+ // An array with a bit vector for each safe point tracking live pointers
+ // in the arguments and locals area, indexed by bb->rpo.
+ Array *argslivepointers;
+ Array *livepointers;
+};
+
+static void*
+xmalloc(uintptr size)
+{
+ void *result;
+
+ result = malloc(size);
+ if(result == nil)
+ fatal("malloc failed");
+ return result;
+}
+
+// Constructs a new basic block containing a single instruction.
+static BasicBlock*
+newblock(Prog *prog)
+{
+ BasicBlock *result;
+
+ if(prog == nil)
+ fatal("newblock: prog cannot be nil");
+ result = xmalloc(sizeof(*result));
+ result->rpo = -1;
+ result->mark = UNVISITED;
+ result->first = prog;
+ result->last = prog;
+ result->pred = arraynew(2, sizeof(BasicBlock*));
+ result->succ = arraynew(2, sizeof(BasicBlock*));
+ return result;
+}
+
+// Frees a basic block and all of its leaf data structures.
+static void
+freeblock(BasicBlock *bb)
+{
+ if(bb == nil)
+ fatal("freeblock: cannot free nil");
+ arrayfree(bb->pred);
+ arrayfree(bb->succ);
+ free(bb);
+}
+
+// Adds an edge between two basic blocks by making from a predecessor of to and
+// to a successor of from.
+static void
+addedge(BasicBlock *from, BasicBlock *to)
+{
+ if(from == nil)
+ fatal("addedge: from is nil");
+ if(to == nil)
+ fatal("addedge: to is nil");
+ arrayadd(from->succ, &to);
+ arrayadd(to->pred, &from);
+}
+
+// Inserts prev before curr in the instruction
+// stream. Any control flow, such as branches or fall throughs, that target the
+// existing instruction are adjusted to target the new instruction.
+static void
+splicebefore(Liveness *lv, BasicBlock *bb, Prog *prev, Prog *curr)
+{
+ Prog *next, tmp;
+
+ USED(lv);
+
+ // There may be other instructions pointing at curr,
+ // and we want them to now point at prev. Instead of
+ // trying to find all such instructions, swap the contents
+ // so that the problem becomes inserting next after curr.
+ // The "opt" field is the backward link in the linked list.
+
+ // Overwrite curr's data with prev, but keep the list links.
+ tmp = *curr;
+ *curr = *prev;
+ curr->opt = tmp.opt;
+ curr->link = tmp.link;
+
+ // Overwrite prev (now next) with curr's old data.
+ next = prev;
+ *next = tmp;
+ next->opt = nil;
+ next->link = nil;
+
+ // Now insert next after curr.
+ next->link = curr->link;
+ next->opt = curr;
+ curr->link = next;
+ if(next->link && next->link->opt == curr)
+ next->link->opt = next;
+
+ if(bb->last == curr)
+ bb->last = next;
+}
+
+// A pretty printer for basic blocks.
+static void
+printblock(BasicBlock *bb)
+{
+ BasicBlock *pred;
+ BasicBlock *succ;
+ Prog *prog;
+ int i;
+
+ print("basic block %d\n", bb->rpo);
+ print("\tpred:");
+ for(i = 0; i < arraylength(bb->pred); i++) {
+ pred = *(BasicBlock**)arrayget(bb->pred, i);
+ print(" %d", pred->rpo);
+ }
+ print("\n");
+ print("\tsucc:");
+ for(i = 0; i < arraylength(bb->succ); i++) {
+ succ = *(BasicBlock**)arrayget(bb->succ, i);
+ print(" %d", succ->rpo);
+ }
+ print("\n");
+ print("\tprog:\n");
+ for(prog = bb->first;; prog=prog->link) {
+ print("\t\t%P\n", prog);
+ if(prog == bb->last)
+ break;
+ }
+}
+
+
+// Iterates over a basic block applying a callback to each instruction. There
+// are two criteria for termination. If the end of basic block is reached a
+// value of zero is returned. If the callback returns a non-zero value, the
+// iteration is stopped and the value of the callback is returned.
+static int
+blockany(BasicBlock *bb, int (*callback)(Prog*))
+{
+ Prog *p;
+ int result;
+
+ for(p = bb->last; p != nil; p = p->opt) {
+ result = (*callback)(p);
+ if(result != 0)
+ return result;
+ }
+ return 0;
+}
+
+// Collects and returns and array of Node*s for functions arguments and local
+// variables.
+static Array*
+getvariables(Node *fn)
+{
+ Array *result;
+ NodeList *ll;
+
+ result = arraynew(0, sizeof(Node*));
+ for(ll = fn->dcl; ll != nil; ll = ll->next) {
+ if(ll->n->op == ONAME) {
+ // In order for GODEBUG=gcdead=1 to work, each bitmap needs
+ // to contain information about all variables covered by the bitmap.
+ // For local variables, the bitmap only covers the stkptrsize
+ // bytes in the frame where variables containing pointers live.
+ // For arguments and results, the bitmap covers all variables,
+ // so we must include all the variables, even the ones without
+ // pointers.
+ switch(ll->n->class) {
+ case PAUTO:
+ if(haspointers(ll->n->type))
+ arrayadd(result, &ll->n);
+ break;
+ case PPARAM:
+ case PPARAMOUT:
+ arrayadd(result, &ll->n);
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+// A pretty printer for control flow graphs. Takes an array of BasicBlock*s.
+static void
+printcfg(Array *cfg)
+{
+ BasicBlock *bb;
+ int32 i;
+
+ for(i = 0; i < arraylength(cfg); i++) {
+ bb = *(BasicBlock**)arrayget(cfg, i);
+ printblock(bb);
+ }
+}
+
+// Assigns a reverse post order number to each connected basic block using the
+// standard algorithm. Unconnected blocks will not be affected.
+static void
+reversepostorder(BasicBlock *root, int32 *rpo)
+{
+ BasicBlock *bb;
+ int i;
+
+ root->mark = VISITED;
+ for(i = 0; i < arraylength(root->succ); i++) {
+ bb = *(BasicBlock**)arrayget(root->succ, i);
+ if(bb->mark == UNVISITED)
+ reversepostorder(bb, rpo);
+ }
+ *rpo -= 1;
+ root->rpo = *rpo;
+}
+
+// Comparison predicate used for sorting basic blocks by their rpo in ascending
+// order.
+static int
+blockrpocmp(const void *p1, const void *p2)
+{
+ BasicBlock *bb1;
+ BasicBlock *bb2;
+
+ bb1 = *(BasicBlock**)p1;
+ bb2 = *(BasicBlock**)p2;
+ if(bb1->rpo < bb2->rpo)
+ return -1;
+ if(bb1->rpo > bb2->rpo)
+ return 1;
+ return 0;
+}
+
+// A pattern matcher for call instructions. Returns true when the instruction
+// is a call to a specific package qualified function name.
+static int
+iscall(Prog *prog, LSym *name)
+{
+ if(prog == nil)
+ fatal("iscall: prog is nil");
+ if(name == nil)
+ fatal("iscall: function name is nil");
+ if(prog->as != ACALL)
+ return 0;
+ return name == prog->to.sym;
+}
+
+// Returns true for instructions that call a runtime function implementing a
+// select communication clause.
+static int
+isselectcommcasecall(Prog *prog)
+{
+ static LSym* names[5];
+ int32 i;
+
+ if(names[0] == nil) {
+ names[0] = linksym(pkglookup("selectsend", runtimepkg));
+ names[1] = linksym(pkglookup("selectrecv", runtimepkg));
+ names[2] = linksym(pkglookup("selectrecv2", runtimepkg));
+ names[3] = linksym(pkglookup("selectdefault", runtimepkg));
+ }
+ for(i = 0; names[i] != nil; i++)
+ if(iscall(prog, names[i]))
+ return 1;
+ return 0;
+}
+
+// Returns true for call instructions that target runtime·newselect.
+static int
+isnewselect(Prog *prog)
+{
+ static LSym *sym;
+
+ if(sym == nil)
+ sym = linksym(pkglookup("newselect", runtimepkg));
+ return iscall(prog, sym);
+}
+
+// Returns true for call instructions that target runtime·selectgo.
+static int
+isselectgocall(Prog *prog)
+{
+ static LSym *sym;
+
+ if(sym == nil)
+ sym = linksym(pkglookup("selectgo", runtimepkg));
+ return iscall(prog, sym);
+}
+
+static int
+isdeferreturn(Prog *prog)
+{
+ static LSym *sym;
+
+ if(sym == nil)
+ sym = linksym(pkglookup("deferreturn", runtimepkg));
+ return iscall(prog, sym);
+}
+
+// Walk backwards from a runtime·selectgo call up to its immediately dominating
+// runtime·newselect call. Any successor nodes of communication clause nodes
+// are implicit successors of the runtime·selectgo call node. The goal of this
+// analysis is to add these missing edges to complete the control flow graph.
+static void
+addselectgosucc(BasicBlock *selectgo)
+{
+ BasicBlock *pred;
+ BasicBlock *succ;
+
+ pred = selectgo;
+ for(;;) {
+ if(arraylength(pred->pred) == 0)
+ fatal("selectgo does not have a newselect");
+ pred = *(BasicBlock**)arrayget(pred->pred, 0);
+ if(blockany(pred, isselectcommcasecall)) {
+ // A select comm case block should have exactly one
+ // successor.
+ if(arraylength(pred->succ) != 1)
+ fatal("select comm case has too many successors");
+ succ = *(BasicBlock**)arrayget(pred->succ, 0);
+ // Its successor should have exactly two successors.
+ // The drop through should flow to the selectgo block
+ // and the branch should lead to the select case
+ // statements block.
+ if(arraylength(succ->succ) != 2)
+ fatal("select comm case successor has too many successors");
+ // Add the block as a successor of the selectgo block.
+ addedge(selectgo, succ);
+ }
+ if(blockany(pred, isnewselect)) {
+ // Reached the matching newselect.
+ break;
+ }
+ }
+}
+
+// The entry point for the missing selectgo control flow algorithm. Takes an
+// array of BasicBlock*s containing selectgo calls.
+static void
+fixselectgo(Array *selectgo)
+{
+ BasicBlock *bb;
+ int32 i;
+
+ for(i = 0; i < arraylength(selectgo); i++) {
+ bb = *(BasicBlock**)arrayget(selectgo, i);
+ addselectgosucc(bb);
+ }
+}
+
+// Constructs a control flow graph from a sequence of instructions. This
+// procedure is complicated by various sources of implicit control flow that are
+// not accounted for using the standard cfg construction algorithm. Returns an
+// array of BasicBlock*s in control flow graph form (basic blocks ordered by
+// their RPO number).
+static Array*
+newcfg(Prog *firstp)
+{
+ Prog *p;
+ Prog *prev;
+ BasicBlock *bb;
+ Array *cfg;
+ Array *selectgo;
+ int32 i;
+ int32 rpo;
+
+ // Reset the opt field of each prog to nil. In the first and second
+ // passes, instructions that are labels temporarily use the opt field to
+ // point to their basic block. In the third pass, the opt field reset
+ // to point to the predecessor of an instruction in its basic block.
+ for(p = firstp; p != P; p = p->link)
+ p->opt = nil;
+
+ // Allocate an array to remember where we have seen selectgo calls.
+ // These blocks will be revisited to add successor control flow edges.
+ selectgo = arraynew(0, sizeof(BasicBlock*));
+
+ // Loop through all instructions identifying branch targets
+ // and fall-throughs and allocate basic blocks.
+ cfg = arraynew(0, sizeof(BasicBlock*));
+ bb = newblock(firstp);
+ arrayadd(cfg, &bb);
+ for(p = firstp; p != P; p = p->link) {
+ if(p->to.type == D_BRANCH) {
+ if(p->to.u.branch == nil)
+ fatal("prog branch to nil");
+ if(p->to.u.branch->opt == nil) {
+ p->to.u.branch->opt = newblock(p->to.u.branch);
+ arrayadd(cfg, &p->to.u.branch->opt);
+ }
+ if(p->as != AJMP && p->link != nil && p->link->opt == nil) {
+ p->link->opt = newblock(p->link);
+ arrayadd(cfg, &p->link->opt);
+ }
+ } else if(isselectcommcasecall(p) || isselectgocall(p)) {
+ // Accommodate implicit selectgo control flow.
+ if(p->link->opt == nil) {
+ p->link->opt = newblock(p->link);
+ arrayadd(cfg, &p->link->opt);
+ }
+ }
+ }
+
+ // Loop through all basic blocks maximally growing the list of
+ // contained instructions until a label is reached. Add edges
+ // for branches and fall-through instructions.
+ for(i = 0; i < arraylength(cfg); i++) {
+ bb = *(BasicBlock**)arrayget(cfg, i);
+ for(p = bb->last; p != nil; p = p->link) {
+ if(p->opt != nil && p != bb->last)
+ break;
+ bb->last = p;
+
+ // Stop before an unreachable RET, to avoid creating
+ // unreachable control flow nodes.
+ if(p->link != nil && p->link->as == ARET && p->link->mode == 1)
+ break;
+
+ // Collect basic blocks with selectgo calls.
+ if(isselectgocall(p))
+ arrayadd(selectgo, &bb);
+ }
+ if(bb->last->to.type == D_BRANCH)
+ addedge(bb, bb->last->to.u.branch->opt);
+ if(bb->last->link != nil) {
+ // Add a fall-through when the instruction is
+ // not an unconditional control transfer.
+ switch(bb->last->as) {
+ case AJMP:
+ case ARET:
+ case AUNDEF:
+ break;
+ default:
+ addedge(bb, bb->last->link->opt);
+ }
+ }
+ }
+
+ // Add back links so the instructions in a basic block can be traversed
+ // backward. This is the final state of the instruction opt field.
+ for(i = 0; i < arraylength(cfg); i++) {
+ bb = *(BasicBlock**)arrayget(cfg, i);
+ p = bb->first;
+ prev = nil;
+ for(;;) {
+ p->opt = prev;
+ if(p == bb->last)
+ break;
+ prev = p;
+ p = p->link;
+ }
+ }
+
+ // Add missing successor edges to the selectgo blocks.
+ if(arraylength(selectgo))
+ fixselectgo(selectgo);
+ arrayfree(selectgo);
+
+ // Find a depth-first order and assign a depth-first number to
+ // all basic blocks.
+ for(i = 0; i < arraylength(cfg); i++) {
+ bb = *(BasicBlock**)arrayget(cfg, i);
+ bb->mark = UNVISITED;
+ }
+ bb = *(BasicBlock**)arrayget(cfg, 0);
+ rpo = arraylength(cfg);
+ reversepostorder(bb, &rpo);
+
+ // Sort the basic blocks by their depth first number. The
+ // array is now a depth-first spanning tree with the first
+ // node being the root.
+ arraysort(cfg, blockrpocmp);
+ bb = *(BasicBlock**)arrayget(cfg, 0);
+
+ // Unreachable control flow nodes are indicated by a -1 in the rpo
+ // field. If we see these nodes something must have gone wrong in an
+ // upstream compilation phase.
+ if(bb->rpo == -1) {
+ print("newcfg: unreachable basic block for %P\n", bb->last);
+ printcfg(cfg);
+ fatal("newcfg: invalid control flow graph");
+ }
+
+ return cfg;
+}
+
+// Frees a control flow graph (an array of BasicBlock*s) and all of its leaf
+// data structures.
+static void
+freecfg(Array *cfg)
+{
+ BasicBlock *bb;
+ BasicBlock *bb0;
+ Prog *p;
+ int32 i;
+ int32 len;
+
+ len = arraylength(cfg);
+ if(len > 0) {
+ bb0 = *(BasicBlock**)arrayget(cfg, 0);
+ for(p = bb0->first; p != P; p = p->link) {
+ p->opt = nil;
+ }
+ for(i = 0; i < len; i++) {
+ bb = *(BasicBlock**)arrayget(cfg, i);
+ freeblock(bb);
+ }
+ }
+ arrayfree(cfg);
+}
+
+// Returns true if the node names a variable that is otherwise uninteresting to
+// the liveness computation.
+static int
+isfunny(Node *node)
+{
+ char *names[] = { ".fp", ".args", nil };
+ int i;
+
+ if(node->sym != nil && node->sym->name != nil)
+ for(i = 0; names[i] != nil; i++)
+ if(strcmp(node->sym->name, names[i]) == 0)
+ return 1;
+ return 0;
+}
+
+// Computes the effects of an instruction on a set of
+// variables. The vars argument is an array of Node*s.
+//
+// The output vectors give bits for variables:
+// uevar - used by this instruction
+// varkill - killed by this instruction
+// for variables without address taken, means variable was set
+// for variables with address taken, means variable was marked dead
+// avarinit - initialized or referred to by this instruction,
+// only for variables with address taken but not escaping to heap
+//
+// The avarinit output serves as a signal that the data has been
+// initialized, because any use of a variable must come after its
+// initialization.
+static void
+progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
+{
+ ProgInfo info;
+ Adr *from;
+ Adr *to;
+ Node *node;
+ int32 i;
+ int32 pos;
+
+ bvresetall(uevar);
+ bvresetall(varkill);
+ bvresetall(avarinit);
+
+ proginfo(&info, prog);
+ if(prog->as == ARET) {
+ // Return instructions implicitly read all the arguments. For
+ // the sake of correctness, out arguments must be read. For the
+ // sake of backtrace quality, we read in arguments as well.
+ //
+ // A return instruction with a p->to is a tail return, which brings
+ // the stack pointer back up (if it ever went down) and then jumps
+ // to a new function entirely. That form of instruction must read
+ // all the parameters for correctness, and similarly it must not
+ // read the out arguments - they won't be set until the new
+ // function runs.
+ for(i = 0; i < arraylength(vars); i++) {
+ node = *(Node**)arrayget(vars, i);
+ switch(node->class & ~PHEAP) {
+ case PPARAM:
+ bvset(uevar, i);
+ break;
+ case PPARAMOUT:
+ // If the result had its address taken, it is being tracked
+ // by the avarinit code, which does not use uevar.
+ // If we added it to uevar too, we'd not see any kill
+ // and decide that the varible was live entry, which it is not.
+ // So only use uevar in the non-addrtaken case.
+ // The p->to.type == D_NONE limits the bvset to
+ // non-tail-call return instructions; see note above
+ // the for loop for details.
+ if(!node->addrtaken && prog->to.type == D_NONE)
+ bvset(uevar, i);
+ break;
+ }
+ }
+ return;
+ }
+ if(prog->as == ATEXT) {
+ // A text instruction marks the entry point to a function and
+ // the definition point of all in arguments.
+ for(i = 0; i < arraylength(vars); i++) {
+ node = *(Node**)arrayget(vars, i);
+ switch(node->class & ~PHEAP) {
+ case PPARAM:
+ if(node->addrtaken)
+ bvset(avarinit, i);
+ bvset(varkill, i);
+ break;
+ }
+ }
+ return;
+ }
+ if(info.flags & (LeftRead | LeftWrite | LeftAddr)) {
+ from = &prog->from;
+ if (from->node != nil && from->sym != nil) {
+ switch(from->node->class & ~PHEAP) {
+ case PAUTO:
+ case PPARAM:
+ case PPARAMOUT:
+ pos = arrayindexof(vars, from->node);
+ if(pos == -1)
+ goto Next;
+ if(from->node->addrtaken) {
+ bvset(avarinit, pos);
+ } else {
+ if(info.flags & (LeftRead | LeftAddr))
+ bvset(uevar, pos);
+ if(info.flags & LeftWrite)
+ if(from->node != nil && !isfat(from->node->type))
+ bvset(varkill, pos);
+ }
+ }
+ }
+ }
+Next:
+ if(info.flags & (RightRead | RightWrite | RightAddr)) {
+ to = &prog->to;
+ if (to->node != nil && to->sym != nil) {
+ switch(to->node->class & ~PHEAP) {
+ case PAUTO:
+ case PPARAM:
+ case PPARAMOUT:
+ pos = arrayindexof(vars, to->node);
+ if(pos == -1)
+ goto Next1;
+ if(to->node->addrtaken) {
+ if(prog->as != AVARKILL)
+ bvset(avarinit, pos);
+ if(prog->as == AVARDEF || prog->as == AVARKILL)
+ bvset(varkill, pos);
+ } else {
+ // RightRead is a read, obviously.
+ // RightAddr by itself is also implicitly a read.
+ //
+ // RightAddr|RightWrite means that the address is being taken
+ // but only so that the instruction can write to the value.
+ // It is not a read. It is equivalent to RightWrite except that
+ // having the RightAddr bit set keeps the registerizer from
+ // trying to substitute a register for the memory location.
+ if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
+ bvset(uevar, pos);
+ if(info.flags & RightWrite)
+ if(to->node != nil && (!isfat(to->node->type) || prog->as == AVARDEF))
+ bvset(varkill, pos);
+ }
+ }
+ }
+ }
+Next1:;
+}
+
+// Constructs a new liveness structure used to hold the global state of the
+// liveness computation. The cfg argument is an array of BasicBlock*s and the
+// vars argument is an array of Node*s.
+static Liveness*
+newliveness(Node *fn, Prog *ptxt, Array *cfg, Array *vars)
+{
+ Liveness *result;
+ int32 i;
+ int32 nblocks;
+ int32 nvars;
+
+ result = xmalloc(sizeof(*result));
+ result->fn = fn;
+ result->ptxt = ptxt;
+ result->cfg = cfg;
+ result->vars = vars;
+
+ nblocks = arraylength(cfg);
+ result->uevar = xmalloc(sizeof(Bvec*) * nblocks);
+ result->varkill = xmalloc(sizeof(Bvec*) * nblocks);
+ result->livein = xmalloc(sizeof(Bvec*) * nblocks);
+ result->liveout = xmalloc(sizeof(Bvec*) * nblocks);
+ result->avarinit = xmalloc(sizeof(Bvec*) * nblocks);
+ result->avarinitany = xmalloc(sizeof(Bvec*) * nblocks);
+ result->avarinitall = xmalloc(sizeof(Bvec*) * nblocks);
+
+ nvars = arraylength(vars);
+ for(i = 0; i < nblocks; i++) {
+ result->uevar[i] = bvalloc(nvars);
+ result->varkill[i] = bvalloc(nvars);
+ result->livein[i] = bvalloc(nvars);
+ result->liveout[i] = bvalloc(nvars);
+ result->avarinit[i] = bvalloc(nvars);
+ result->avarinitany[i] = bvalloc(nvars);
+ result->avarinitall[i] = bvalloc(nvars);
+ }
+
+ result->livepointers = arraynew(0, sizeof(Bvec*));
+ result->argslivepointers = arraynew(0, sizeof(Bvec*));
+ return result;
+}
+
+// Frees the liveness structure and all of its leaf data structures.
+static void
+freeliveness(Liveness *lv)
+{
+ int32 i;
+
+ if(lv == nil)
+ fatal("freeliveness: cannot free nil");
+
+ for(i = 0; i < arraylength(lv->livepointers); i++)
+ free(*(Bvec**)arrayget(lv->livepointers, i));
+ arrayfree(lv->livepointers);
+
+ for(i = 0; i < arraylength(lv->argslivepointers); i++)
+ free(*(Bvec**)arrayget(lv->argslivepointers, i));
+ arrayfree(lv->argslivepointers);
+
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ free(lv->uevar[i]);
+ free(lv->varkill[i]);
+ free(lv->livein[i]);
+ free(lv->liveout[i]);
+ free(lv->avarinit[i]);
+ free(lv->avarinitany[i]);
+ free(lv->avarinitall[i]);
+ }
+
+ free(lv->uevar);
+ free(lv->varkill);
+ free(lv->livein);
+ free(lv->liveout);
+ free(lv->avarinit);
+ free(lv->avarinitany);
+ free(lv->avarinitall);
+
+ free(lv);
+}
+
+static void
+printeffects(Prog *p, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
+{
+ print("effects of %P", p);
+ print("\nuevar: ");
+ bvprint(uevar);
+ print("\nvarkill: ");
+ bvprint(varkill);
+ print("\navarinit: ");
+ bvprint(avarinit);
+ print("\n");
+}
+
+// Pretty print a variable node. Uses Pascal like conventions for pointers and
+// addresses to avoid confusing the C like conventions used in the node variable
+// names.
+static void
+printnode(Node *node)
+{
+ char *p;
+ char *a;
+
+ p = haspointers(node->type) ? "^" : "";
+ a = node->addrtaken ? "@" : "";
+ print(" %N%s%s", node, p, a);
+}
+
+// Pretty print a list of variables. The vars argument is an array of Node*s.
+static void
+printvars(char *name, Bvec *bv, Array *vars)
+{
+ int32 i;
+
+ print("%s:", name);
+ for(i = 0; i < arraylength(vars); i++)
+ if(bvget(bv, i))
+ printnode(*(Node**)arrayget(vars, i));
+ print("\n");
+}
+
+// Prints a basic block annotated with the information computed by liveness
+// analysis.
+static void
+livenessprintblock(Liveness *lv, BasicBlock *bb)
+{
+ BasicBlock *pred;
+ BasicBlock *succ;
+ Prog *prog;
+ Bvec *live;
+ int i;
+ int32 pos;
+
+ print("basic block %d\n", bb->rpo);
+
+ print("\tpred:");
+ for(i = 0; i < arraylength(bb->pred); i++) {
+ pred = *(BasicBlock**)arrayget(bb->pred, i);
+ print(" %d", pred->rpo);
+ }
+ print("\n");
+
+ print("\tsucc:");
+ for(i = 0; i < arraylength(bb->succ); i++) {
+ succ = *(BasicBlock**)arrayget(bb->succ, i);
+ print(" %d", succ->rpo);
+ }
+ print("\n");
+
+ printvars("\tuevar", lv->uevar[bb->rpo], lv->vars);
+ printvars("\tvarkill", lv->varkill[bb->rpo], lv->vars);
+ printvars("\tlivein", lv->livein[bb->rpo], lv->vars);
+ printvars("\tliveout", lv->liveout[bb->rpo], lv->vars);
+ printvars("\tavarinit", lv->avarinit[bb->rpo], lv->vars);
+ printvars("\tavarinitany", lv->avarinitany[bb->rpo], lv->vars);
+ printvars("\tavarinitall", lv->avarinitall[bb->rpo], lv->vars);
+
+ print("\tprog:\n");
+ for(prog = bb->first;; prog = prog->link) {
+ print("\t\t%P", prog);
+ if(prog->as == APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
+ pos = prog->to.offset;
+ live = *(Bvec**)arrayget(lv->livepointers, pos);
+ print(" ");
+ bvprint(live);
+ }
+ print("\n");
+ if(prog == bb->last)
+ break;
+ }
+}
+
+// Prints a control flow graph annotated with any information computed by
+// liveness analysis.
+static void
+livenessprintcfg(Liveness *lv)
+{
+ BasicBlock *bb;
+ int32 i;
+
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+ livenessprintblock(lv, bb);
+ }
+}
+
+static void
+checkauto(Node *fn, Prog *p, Node *n)
+{
+ NodeList *l;
+
+ for(l = fn->dcl; l != nil; l = l->next)
+ if(l->n->op == ONAME && l->n->class == PAUTO && l->n == n)
+ return;
+
+ print("checkauto %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
+ for(l = fn->dcl; l != nil; l = l->next)
+ print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
+ yyerror("checkauto: invariant lost");
+}
+
+static void
+checkparam(Node *fn, Prog *p, Node *n)
+{
+ NodeList *l;
+ Node *a;
+ int class;
+
+ if(isfunny(n))
+ return;
+ for(l = fn->dcl; l != nil; l = l->next) {
+ a = l->n;
+ class = a->class & ~PHEAP;
+ if(a->op == ONAME && (class == PPARAM || class == PPARAMOUT) && a == n)
+ return;
+ }
+
+ print("checkparam %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
+ for(l = fn->dcl; l != nil; l = l->next)
+ print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
+ yyerror("checkparam: invariant lost");
+}
+
+static void
+checkprog(Node *fn, Prog *p)
+{
+ if(p->from.type == D_AUTO)
+ checkauto(fn, p, p->from.node);
+ if(p->from.type == D_PARAM)
+ checkparam(fn, p, p->from.node);
+ if(p->to.type == D_AUTO)
+ checkauto(fn, p, p->to.node);
+ if(p->to.type == D_PARAM)
+ checkparam(fn, p, p->to.node);
+}
+
+// Check instruction invariants. We assume that the nodes corresponding to the
+// sources and destinations of memory operations will be declared in the
+// function. This is not strictly true, as is the case for the so-called funny
+// nodes and there are special cases to skip over that stuff. The analysis will
+// fail if this invariant blindly changes.
+static void
+checkptxt(Node *fn, Prog *firstp)
+{
+ Prog *p;
+
+ for(p = firstp; p != P; p = p->link) {
+ if(0)
+ print("analyzing '%P'\n", p);
+ switch(p->as) {
+ case ADATA:
+ case AGLOBL:
+ case ANAME:
+ case ASIGNAME:
+ case ATYPE:
+ continue;
+ }
+ checkprog(fn, p);
+ }
+}
+
+// NOTE: The bitmap for a specific type t should be cached in t after the first run
+// and then simply copied into bv at the correct offset on future calls with
+// the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, twobitwalktype1
+// accounts for 40% of the 6g execution time.
+static void
+twobitwalktype1(Type *t, vlong *xoffset, Bvec *bv)
+{
+ vlong fieldoffset;
+ vlong i;
+ vlong o;
+ Type *t1;
+
+ if(t->align > 0 && (*xoffset & (t->align - 1)) != 0)
+ fatal("twobitwalktype1: invalid initial alignment, %T", t);
+
+ switch(t->etype) {
+ case TINT8:
+ case TUINT8:
+ case TINT16:
+ case TUINT16:
+ case TINT32:
+ case TUINT32:
+ case TINT64:
+ case TUINT64:
+ case TINT:
+ case TUINT:
+ case TUINTPTR:
+ case TBOOL:
+ case TFLOAT32:
+ case TFLOAT64:
+ case TCOMPLEX64:
+ case TCOMPLEX128:
+ for(i = 0; i < t->width; i++) {
+ bvset(bv, ((*xoffset + i) / widthptr) * BitsPerPointer); // 1 = live scalar
+ }
+ *xoffset += t->width;
+ break;
+
+ case TPTR32:
+ case TPTR64:
+ case TUNSAFEPTR:
+ case TFUNC:
+ case TCHAN:
+ case TMAP:
+ if((*xoffset & (widthptr-1)) != 0)
+ fatal("twobitwalktype1: invalid alignment, %T", t);
+ bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr
+ *xoffset += t->width;
+ break;
+
+ case TSTRING:
+ // struct { byte *str; intgo len; }
+ if((*xoffset & (widthptr-1)) != 0)
+ fatal("twobitwalktype1: invalid alignment, %T", t);
+ bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 0);
+ bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 3:0 = multiword:string
+ *xoffset += t->width;
+ break;
+
+ case TINTER:
+ // struct { Itab *tab; union { void *ptr, uintptr val } data; }
+ // or, when isnilinter(t)==true:
+ // struct { Type *type; union { void *ptr, uintptr val } data; }
+ if((*xoffset & (widthptr-1)) != 0)
+ fatal("twobitwalktype1: invalid alignment, %T", t);
+ bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 0);
+ bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1); // 3 = multiword
+ // next word contains 2 = Iface, 3 = Eface
+ if(isnilinter(t)) {
+ bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 2);
+ bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 3);
+ } else {
+ bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 3);
+ }
+ *xoffset += t->width;
+ break;
+
+ case TARRAY:
+ // The value of t->bound is -1 for slices types and >0 for
+ // for fixed array types. All other values are invalid.
+ if(t->bound < -1)
+ fatal("twobitwalktype1: invalid bound, %T", t);
+ if(isslice(t)) {
+ // struct { byte *array; uintgo len; uintgo cap; }
+ if((*xoffset & (widthptr-1)) != 0)
+ fatal("twobitwalktype1: invalid TARRAY alignment, %T", t);
+ bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 0);
+ bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1);
+ bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 2); // 3:1 = multiword/slice
+ *xoffset += t->width;
+ } else
+ for(i = 0; i < t->bound; i++)
+ twobitwalktype1(t->type, xoffset, bv);
+ break;
+
+ case TSTRUCT:
+ o = 0;
+ for(t1 = t->type; t1 != T; t1 = t1->down) {
+ fieldoffset = t1->width;
+ *xoffset += fieldoffset - o;
+ twobitwalktype1(t1->type, xoffset, bv);
+ o = fieldoffset + t1->type->width;
+ }
+ *xoffset += t->width - o;
+ break;
+
+ default:
+ fatal("twobitwalktype1: unexpected type, %T", t);
+ }
+}
+
+// Returns the number of words of local variables.
+static int32
+localswords(void)
+{
+ return stkptrsize / widthptr;
+}
+
+// Returns the number of words of in and out arguments.
+static int32
+argswords(void)
+{
+ return curfn->type->argwid / widthptr;
+}
+
+// Generates live pointer value maps for arguments and local variables. The
+// this argument and the in arguments are always assumed live. The vars
+// argument is an array of Node*s.
+static void
+twobitlivepointermap(Liveness *lv, Bvec *liveout, Array *vars, Bvec *args, Bvec *locals)
+{
+ Node *node;
+ Type *thisargtype;
+ Type *inargtype;
+ vlong xoffset;
+ int32 i;
+
+ for(i = 0; i < arraylength(vars); i++) {
+ node = *(Node**)arrayget(vars, i);
+ switch(node->class) {
+ case PAUTO:
+ if(bvget(liveout, i)) {
+ xoffset = node->xoffset + stkptrsize;
+ twobitwalktype1(node->type, &xoffset, locals);
+ }
+ break;
+ case PPARAM:
+ case PPARAMOUT:
+ if(bvget(liveout, i)) {
+ xoffset = node->xoffset;
+ twobitwalktype1(node->type, &xoffset, args);
+ }
+ break;
+ }
+ }
+
+ // The node list only contains declared names.
+ // If the receiver or arguments are unnamed, they will be omitted
+ // from the list above. Preserve those values - even though they are unused -
+ // in order to keep their addresses live for use in stack traces.
+ thisargtype = getthisx(lv->fn->type);
+ if(thisargtype != nil) {
+ xoffset = 0;
+ twobitwalktype1(thisargtype, &xoffset, args);
+ }
+ inargtype = getinargx(lv->fn->type);
+ if(inargtype != nil) {
+ xoffset = 0;
+ twobitwalktype1(inargtype, &xoffset, args);
+ }
+}
+
+// Construct a disembodied instruction.
+static Prog*
+unlinkedprog(int as)
+{
+ Prog *p;
+
+ p = mal(sizeof(*p));
+ clearp(p);
+ p->as = as;
+ return p;
+}
+
+// Construct a new PCDATA instruction associated with and for the purposes of
+// covering an existing instruction.
+static Prog*
+newpcdataprog(Prog *prog, int32 index)
+{
+ Node from, to;
+ Prog *pcdata;
+
+ nodconst(&from, types[TINT32], PCDATA_StackMapIndex);
+ nodconst(&to, types[TINT32], index);
+ pcdata = unlinkedprog(APCDATA);
+ pcdata->lineno = prog->lineno;
+ naddr(&from, &pcdata->from, 0);
+ naddr(&to, &pcdata->to, 0);
+ return pcdata;
+}
+
+// Returns true for instructions that are safe points that must be annotated
+// with liveness information.
+static int
+issafepoint(Prog *prog)
+{
+ return prog->as == ATEXT || prog->as == ACALL;
+}
+
+// Initializes the sets for solving the live variables. Visits all the
+// instructions in each basic block to summarizes the information at each basic
+// block
+static void
+livenessprologue(Liveness *lv)
+{
+ BasicBlock *bb;
+ Bvec *uevar, *varkill, *avarinit;
+ Prog *p;
+ int32 i;
+ int32 nvars;
+
+ nvars = arraylength(lv->vars);
+ uevar = bvalloc(nvars);
+ varkill = bvalloc(nvars);
+ avarinit = bvalloc(nvars);
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+ // Walk the block instructions backward and update the block
+ // effects with the each prog effects.
+ for(p = bb->last; p != nil; p = p->opt) {
+ progeffects(p, lv->vars, uevar, varkill, avarinit);
+ if(debuglive >= 3)
+ printeffects(p, uevar, varkill, avarinit);
+ bvor(lv->varkill[i], lv->varkill[i], varkill);
+ bvandnot(lv->uevar[i], lv->uevar[i], varkill);
+ bvor(lv->uevar[i], lv->uevar[i], uevar);
+ }
+ // Walk the block instructions forward to update avarinit bits.
+ // avarinit describes the effect at the end of the block, not the beginning.
+ bvresetall(varkill);
+ for(p = bb->first;; p = p->link) {
+ progeffects(p, lv->vars, uevar, varkill, avarinit);
+ if(debuglive >= 3)
+ printeffects(p, uevar, varkill, avarinit);
+ bvandnot(lv->avarinit[i], lv->avarinit[i], varkill);
+ bvor(lv->avarinit[i], lv->avarinit[i], avarinit);
+ if(p == bb->last)
+ break;
+ }
+ }
+ free(uevar);
+ free(varkill);
+ free(avarinit);
+}
+
+// Solve the liveness dataflow equations.
+static void
+livenesssolve(Liveness *lv)
+{
+ BasicBlock *bb, *succ, *pred;
+ Bvec *newlivein, *newliveout, *any, *all;
+ int32 rpo, i, j, change;
+
+ // These temporary bitvectors exist to avoid successive allocations and
+ // frees within the loop.
+ newlivein = bvalloc(arraylength(lv->vars));
+ newliveout = bvalloc(arraylength(lv->vars));
+ any = bvalloc(arraylength(lv->vars));
+ all = bvalloc(arraylength(lv->vars));
+
+ // Push avarinitall, avarinitany forward.
+ // avarinitall says the addressed var is initialized along all paths reaching the block exit.
+ // avarinitany says the addressed var is initialized along some path reaching the block exit.
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+ rpo = bb->rpo;
+ if(i == 0)
+ bvcopy(lv->avarinitall[rpo], lv->avarinit[rpo]);
+ else {
+ bvresetall(lv->avarinitall[rpo]);
+ bvnot(lv->avarinitall[rpo]);
+ }
+ bvcopy(lv->avarinitany[rpo], lv->avarinit[rpo]);
+ }
+
+ change = 1;
+ while(change != 0) {
+ change = 0;
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+ rpo = bb->rpo;
+ bvresetall(any);
+ bvresetall(all);
+ for(j = 0; j < arraylength(bb->pred); j++) {
+ pred = *(BasicBlock**)arrayget(bb->pred, j);
+ if(j == 0) {
+ bvcopy(any, lv->avarinitany[pred->rpo]);
+ bvcopy(all, lv->avarinitall[pred->rpo]);
+ } else {
+ bvor(any, any, lv->avarinitany[pred->rpo]);
+ bvand(all, all, lv->avarinitall[pred->rpo]);
+ }
+ }
+ bvandnot(any, any, lv->varkill[rpo]);
+ bvandnot(all, all, lv->varkill[rpo]);
+ bvor(any, any, lv->avarinit[rpo]);
+ bvor(all, all, lv->avarinit[rpo]);
+ if(bvcmp(any, lv->avarinitany[rpo])) {
+ change = 1;
+ bvcopy(lv->avarinitany[rpo], any);
+ }
+ if(bvcmp(all, lv->avarinitall[rpo])) {
+ change = 1;
+ bvcopy(lv->avarinitall[rpo], all);
+ }
+ }
+ }
+
+ // Iterate through the blocks in reverse round-robin fashion. A work
+ // queue might be slightly faster. As is, the number of iterations is
+ // so low that it hardly seems to be worth the complexity.
+ change = 1;
+ while(change != 0) {
+ change = 0;
+ // Walk blocks in the general direction of propagation. This
+ // improves convergence.
+ for(i = arraylength(lv->cfg) - 1; i >= 0; i--) {
+ // A variable is live on output from this block
+ // if it is live on input to some successor.
+ //
+ // out[b] = \bigcup_{s \in succ[b]} in[s]
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+ rpo = bb->rpo;
+ bvresetall(newliveout);
+ for(j = 0; j < arraylength(bb->succ); j++) {
+ succ = *(BasicBlock**)arrayget(bb->succ, j);
+ bvor(newliveout, newliveout, lv->livein[succ->rpo]);
+ }
+ if(bvcmp(lv->liveout[rpo], newliveout)) {
+ change = 1;
+ bvcopy(lv->liveout[rpo], newliveout);
+ }
+
+ // A variable is live on input to this block
+ // if it is live on output from this block and
+ // not set by the code in this block.
+ //
+ // in[b] = uevar[b] \cup (out[b] \setminus varkill[b])
+ bvandnot(newlivein, lv->liveout[rpo], lv->varkill[rpo]);
+ bvor(lv->livein[rpo], newlivein, lv->uevar[rpo]);
+ }
+ }
+
+ free(newlivein);
+ free(newliveout);
+ free(any);
+ free(all);
+}
+
+// This function is slow but it is only used for generating debug prints.
+// Check whether n is marked live in args/locals.
+static int
+islive(Node *n, Bvec *args, Bvec *locals)
+{
+ int i;
+
+ switch(n->class) {
+ case PPARAM:
+ case PPARAMOUT:
+ for(i = 0; i < n->type->width/widthptr*BitsPerPointer; i++)
+ if(bvget(args, n->xoffset/widthptr*BitsPerPointer + i))
+ return 1;
+ break;
+ case PAUTO:
+ for(i = 0; i < n->type->width/widthptr*BitsPerPointer; i++)
+ if(bvget(locals, (n->xoffset + stkptrsize)/widthptr*BitsPerPointer + i))
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+// Visits all instructions in a basic block and computes a bit vector of live
+// variables at each safe point locations.
+static void
+livenessepilogue(Liveness *lv)
+{
+ BasicBlock *bb, *pred;
+ Bvec *ambig, *livein, *liveout, *uevar, *varkill, *args, *locals, *avarinit, *any, *all;
+ Node *n;
+ Prog *p, *next;
+ int32 i, j, numlive, startmsg, nmsg, nvars, pos;
+ vlong xoffset;
+ char **msg;
+ Fmt fmt;
+
+ nvars = arraylength(lv->vars);
+ livein = bvalloc(nvars);
+ liveout = bvalloc(nvars);
+ uevar = bvalloc(nvars);
+ varkill = bvalloc(nvars);
+ avarinit = bvalloc(nvars);
+ any = bvalloc(nvars);
+ all = bvalloc(nvars);
+ ambig = bvalloc(localswords() * BitsPerPointer);
+ msg = nil;
+ nmsg = 0;
+ startmsg = 0;
+
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+
+ // Compute avarinitany and avarinitall for entry to block.
+ // This duplicates information known during livenesssolve
+ // but avoids storing two more vectors for each block.
+ bvresetall(any);
+ bvresetall(all);
+ for(j = 0; j < arraylength(bb->pred); j++) {
+ pred = *(BasicBlock**)arrayget(bb->pred, j);
+ if(j == 0) {
+ bvcopy(any, lv->avarinitany[pred->rpo]);
+ bvcopy(all, lv->avarinitall[pred->rpo]);
+ } else {
+ bvor(any, any, lv->avarinitany[pred->rpo]);
+ bvand(all, all, lv->avarinitall[pred->rpo]);
+ }
+ }
+
+ // Walk forward through the basic block instructions and
+ // allocate liveness maps for those instructions that need them.
+ // Seed the maps with information about the addrtaken variables.
+ for(p = bb->first;; p = p->link) {
+ progeffects(p, lv->vars, uevar, varkill, avarinit);
+ bvandnot(any, any, varkill);
+ bvandnot(all, all, varkill);
+ bvor(any, any, avarinit);
+ bvor(all, all, avarinit);
+
+ if(issafepoint(p)) {
+ // Annotate ambiguously live variables so that they can
+ // be zeroed at function entry.
+ // livein and liveout are dead here and used as temporaries.
+ // For now, only enabled when using GOEXPERIMENT=precisestack
+ // during make.bash / all.bash.
+ if(precisestack_enabled) {
+ bvresetall(livein);
+ bvandnot(liveout, any, all);
+ if(!bvisempty(liveout)) {
+ for(pos = 0; pos < liveout->n; pos++) {
+ if(!bvget(liveout, pos))
+ continue;
+ bvset(all, pos); // silence future warnings in this block
+ n = *(Node**)arrayget(lv->vars, pos);
+ if(!n->needzero) {
+ n->needzero = 1;
+ if(debuglive >= 1)
+ warnl(p->lineno, "%N: %lN is ambiguously live", curfn->nname, n);
+ // Record in 'ambiguous' bitmap.
+ xoffset = n->xoffset + stkptrsize;
+ twobitwalktype1(n->type, &xoffset, ambig);
+ }
+ }
+ }
+ }
+
+ // Allocate a bit vector for each class and facet of
+ // value we are tracking.
+
+ // Live stuff first.
+ args = bvalloc(argswords() * BitsPerPointer);
+ arrayadd(lv->argslivepointers, &args);
+ locals = bvalloc(localswords() * BitsPerPointer);
+ arrayadd(lv->livepointers, &locals);
+
+ if(debuglive >= 3) {
+ print("%P\n", p);
+ printvars("avarinitany", any, lv->vars);
+ }
+
+ // Record any values with an "address taken" reaching
+ // this code position as live. Must do now instead of below
+ // because the any/all calculation requires walking forward
+ // over the block (as this loop does), while the liveout
+ // requires walking backward (as the next loop does).
+ twobitlivepointermap(lv, any, lv->vars, args, locals);
+ }
+
+ if(p == bb->last)
+ break;
+ }
+ bb->lastbitmapindex = arraylength(lv->livepointers) - 1;
+ }
+
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+
+ if(debuglive >= 1 && strcmp(curfn->nname->sym->name, "init") != 0 && curfn->nname->sym->name[0] != '.') {
+ nmsg = arraylength(lv->livepointers);
+ startmsg = nmsg;
+ msg = xmalloc(nmsg*sizeof msg[0]);
+ for(j=0; j<nmsg; j++)
+ msg[j] = nil;
+ }
+
+ // walk backward, emit pcdata and populate the maps
+ pos = bb->lastbitmapindex;
+ if(pos < 0) {
+ // the first block we encounter should have the ATEXT so
+ // at no point should pos ever be less than zero.
+ fatal("livenessepilogue");
+ }
+
+ bvcopy(livein, lv->liveout[bb->rpo]);
+ for(p = bb->last; p != nil; p = next) {
+ next = p->opt; // splicebefore modifies p->opt
+ // Propagate liveness information
+ progeffects(p, lv->vars, uevar, varkill, avarinit);
+ bvcopy(liveout, livein);
+ bvandnot(livein, liveout, varkill);
+ bvor(livein, livein, uevar);
+ if(debuglive >= 3 && issafepoint(p)){
+ print("%P\n", p);
+ printvars("uevar", uevar, lv->vars);
+ printvars("varkill", varkill, lv->vars);
+ printvars("livein", livein, lv->vars);
+ printvars("liveout", liveout, lv->vars);
+ }
+ if(issafepoint(p)) {
+ // Found an interesting instruction, record the
+ // corresponding liveness information.
+
+ // Useful sanity check: on entry to the function,
+ // the only things that can possibly be live are the
+ // input parameters.
+ if(p->as == ATEXT) {
+ for(j = 0; j < liveout->n; j++) {
+ if(!bvget(liveout, j))
+ continue;
+ n = *(Node**)arrayget(lv->vars, j);
+ if(n->class != PPARAM)
+ yyerrorl(p->lineno, "internal error: %N %lN recorded as live on entry", curfn->nname, n);
+ }
+ }
+
+ // Record live pointers.
+ args = *(Bvec**)arrayget(lv->argslivepointers, pos);
+ locals = *(Bvec**)arrayget(lv->livepointers, pos);
+ twobitlivepointermap(lv, liveout, lv->vars, args, locals);
+
+ // Ambiguously live variables are zeroed immediately after
+ // function entry. Mark them live for all the non-entry bitmaps
+ // so that GODEBUG=gcdead=1 mode does not poison them.
+ if(p->as == ACALL)
+ bvor(locals, locals, ambig);
+
+ // Show live pointer bitmaps.
+ // We're interpreting the args and locals bitmap instead of liveout so that we
+ // include the bits added by the avarinit logic in the
+ // previous loop.
+ if(msg != nil) {
+ fmtstrinit(&fmt);
+ fmtprint(&fmt, "%L: live at ", p->lineno);
+ if(p->as == ACALL && p->to.node)
+ fmtprint(&fmt, "call to %s:", p->to.node->sym->name);
+ else if(p->as == ACALL)
+ fmtprint(&fmt, "indirect call:");
+ else
+ fmtprint(&fmt, "entry to %s:", p->from.node->sym->name);
+ numlive = 0;
+ for(j = 0; j < arraylength(lv->vars); j++) {
+ n = *(Node**)arrayget(lv->vars, j);
+ if(islive(n, args, locals)) {
+ fmtprint(&fmt, " %N", n);
+ numlive++;
+ }
+ }
+ fmtprint(&fmt, "\n");
+ if(numlive == 0) // squelch message
+ free(fmtstrflush(&fmt));
+ else
+ msg[--startmsg] = fmtstrflush(&fmt);
+ }
+
+ // Only CALL instructions need a PCDATA annotation.
+ // The TEXT instruction annotation is implicit.
+ if(p->as == ACALL) {
+ if(isdeferreturn(p)) {
+ // runtime.deferreturn modifies its return address to return
+ // back to the CALL, not to the subsequent instruction.
+ // Because the return comes back one instruction early,
+ // the PCDATA must begin one instruction early too.
+ // The instruction before a call to deferreturn is always a
+ // no-op, to keep PC-specific data unambiguous.
+ splicebefore(lv, bb, newpcdataprog(p->opt, pos), p->opt);
+ } else {
+ splicebefore(lv, bb, newpcdataprog(p, pos), p);
+ }
+ }
+
+ pos--;
+ }
+ }
+ if(msg != nil) {
+ for(j=startmsg; j<nmsg; j++)
+ if(msg[j] != nil)
+ print("%s", msg[j]);
+ free(msg);
+ msg = nil;
+ nmsg = 0;
+ startmsg = 0;
+ }
+ }
+
+ free(livein);
+ free(liveout);
+ free(uevar);
+ free(varkill);
+ free(avarinit);
+ free(any);
+ free(all);
+ free(ambig);
+
+ flusherrors();
+}
+
+// FNV-1 hash function constants.
+#define H0 2166136261UL
+#define Hp 16777619UL
+
+static uint32
+hashbitmap(uint32 h, Bvec *bv)
+{
+ uchar *p, *ep;
+
+ p = (uchar*)bv->b;
+ ep = p + 4*((bv->n+31)/32);
+ while(p < ep)
+ h = (h*Hp) ^ *p++;
+ return h;
+}
+
+// Compact liveness information by coalescing identical per-call-site bitmaps.
+// The merging only happens for a single function, not across the entire binary.
+//
+// There are actually two lists of bitmaps, one list for the local variables and one
+// list for the function arguments. Both lists are indexed by the same PCDATA
+// index, so the corresponding pairs must be considered together when
+// merging duplicates. The argument bitmaps change much less often during
+// function execution than the local variable bitmaps, so it is possible that
+// we could introduce a separate PCDATA index for arguments vs locals and
+// then compact the set of argument bitmaps separately from the set of
+// local variable bitmaps. As of 2014-04-02, doing this to the godoc binary
+// is actually a net loss: we save about 50k of argument bitmaps but the new
+// PCDATA tables cost about 100k. So for now we keep using a single index for
+// both bitmap lists.
+static void
+livenesscompact(Liveness *lv)
+{
+ int *table, *remap, i, j, n, tablesize, uniq;
+ uint32 h;
+ Bvec *local, *arg, *jlocal, *jarg;
+ Prog *p;
+
+ // Linear probing hash table of bitmaps seen so far.
+ // The hash table has 4n entries to keep the linear
+ // scan short. An entry of -1 indicates an empty slot.
+ n = arraylength(lv->livepointers);
+ tablesize = 4*n;
+ table = xmalloc(tablesize*sizeof table[0]);
+ memset(table, 0xff, tablesize*sizeof table[0]);
+
+ // remap[i] = the new index of the old bit vector #i.
+ remap = xmalloc(n*sizeof remap[0]);
+ memset(remap, 0xff, n*sizeof remap[0]);
+ uniq = 0; // unique tables found so far
+
+ // Consider bit vectors in turn.
+ // If new, assign next number using uniq,
+ // record in remap, record in lv->livepointers and lv->argslivepointers
+ // under the new index, and add entry to hash table.
+ // If already seen, record earlier index in remap and free bitmaps.
+ for(i=0; i<n; i++) {
+ local = *(Bvec**)arrayget(lv->livepointers, i);
+ arg = *(Bvec**)arrayget(lv->argslivepointers, i);
+ h = hashbitmap(hashbitmap(H0, local), arg) % tablesize;
+
+ for(;;) {
+ j = table[h];
+ if(j < 0)
+ break;
+ jlocal = *(Bvec**)arrayget(lv->livepointers, j);
+ jarg = *(Bvec**)arrayget(lv->argslivepointers, j);
+ if(bvcmp(local, jlocal) == 0 && bvcmp(arg, jarg) == 0) {
+ free(local);
+ free(arg);
+ remap[i] = j;
+ goto Next;
+ }
+ if(++h == tablesize)
+ h = 0;
+ }
+ table[h] = uniq;
+ remap[i] = uniq;
+ *(Bvec**)arrayget(lv->livepointers, uniq) = local;
+ *(Bvec**)arrayget(lv->argslivepointers, uniq) = arg;
+ uniq++;
+ Next:;
+ }
+
+ // We've already reordered lv->livepointers[0:uniq]
+ // and lv->argslivepointers[0:uniq] and freed the bitmaps
+ // we don't need anymore. Clear the pointers later in the
+ // array so that we can tell where the coalesced bitmaps stop
+ // and so that we don't double-free when cleaning up.
+ for(j=uniq; j<n; j++) {
+ *(Bvec**)arrayget(lv->livepointers, j) = nil;
+ *(Bvec**)arrayget(lv->argslivepointers, j) = nil;
+ }
+
+ // Rewrite PCDATA instructions to use new numbering.
+ for(p=lv->ptxt; p != P; p=p->link) {
+ if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) {
+ i = p->to.offset;
+ if(i >= 0)
+ p->to.offset = remap[i];
+ }
+ }
+
+ free(table);
+ free(remap);
+}
+
+static int
+printbitset(int printed, char *name, Array *vars, Bvec *bits)
+{
+ int i, started;
+ Node *n;
+
+ started = 0;
+ for(i=0; i<arraylength(vars); i++) {
+ if(!bvget(bits, i))
+ continue;
+ if(!started) {
+ if(!printed)
+ print("\t");
+ else
+ print(" ");
+ started = 1;
+ printed = 1;
+ print("%s=", name);
+ } else {
+ print(",");
+ }
+ n = *(Node**)arrayget(vars, i);
+ print("%s", n->sym->name);
+ }
+ return printed;
+}
+
+// Prints the computed liveness information and inputs, for debugging.
+// This format synthesizes the information used during the multiple passes
+// into a single presentation.
+static void
+livenessprintdebug(Liveness *lv)
+{
+ int i, j, pcdata, printed;
+ BasicBlock *bb;
+ Prog *p;
+ Bvec *uevar, *varkill, *avarinit, *args, *locals;
+ Node *n;
+
+ print("liveness: %s\n", curfn->nname->sym->name);
+
+ uevar = bvalloc(arraylength(lv->vars));
+ varkill = bvalloc(arraylength(lv->vars));
+ avarinit = bvalloc(arraylength(lv->vars));
+
+ pcdata = 0;
+ for(i = 0; i < arraylength(lv->cfg); i++) {
+ if(i > 0)
+ print("\n");
+ bb = *(BasicBlock**)arrayget(lv->cfg, i);
+
+ // bb#0 pred=1,2 succ=3,4
+ print("bb#%d pred=", i);
+ for(j = 0; j < arraylength(bb->pred); j++) {
+ if(j > 0)
+ print(",");
+ print("%d", (*(BasicBlock**)arrayget(bb->pred, j))->rpo);
+ }
+ print(" succ=");
+ for(j = 0; j < arraylength(bb->succ); j++) {
+ if(j > 0)
+ print(",");
+ print("%d", (*(BasicBlock**)arrayget(bb->succ, j))->rpo);
+ }
+ print("\n");
+
+ // initial settings
+ printed = 0;
+ printed = printbitset(printed, "uevar", lv->vars, lv->uevar[bb->rpo]);
+ printed = printbitset(printed, "livein", lv->vars, lv->livein[bb->rpo]);
+ if(printed)
+ print("\n");
+
+ // program listing, with individual effects listed
+ for(p = bb->first;; p = p->link) {
+ print("%P\n", p);
+ if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex)
+ pcdata = p->to.offset;
+ progeffects(p, lv->vars, uevar, varkill, avarinit);
+ printed = 0;
+ printed = printbitset(printed, "uevar", lv->vars, uevar);
+ printed = printbitset(printed, "varkill", lv->vars, varkill);
+ printed = printbitset(printed, "avarinit", lv->vars, avarinit);
+ if(printed)
+ print("\n");
+ if(issafepoint(p)) {
+ args = *(Bvec**)arrayget(lv->argslivepointers, pcdata);
+ locals = *(Bvec**)arrayget(lv->livepointers, pcdata);
+ print("\tlive=");
+ printed = 0;
+ for(j = 0; j < arraylength(lv->vars); j++) {
+ n = *(Node**)arrayget(lv->vars, j);
+ if(islive(n, args, locals)) {
+ if(printed++)
+ print(",");
+ print("%N", n);
+ }
+ }
+ print("\n");
+ }
+ if(p == bb->last)
+ break;
+ }
+
+ // bb bitsets
+ print("end\n");
+ printed = printbitset(printed, "varkill", lv->vars, lv->varkill[bb->rpo]);
+ printed = printbitset(printed, "liveout", lv->vars, lv->liveout[bb->rpo]);
+ printed = printbitset(printed, "avarinit", lv->vars, lv->avarinit[bb->rpo]);
+ printed = printbitset(printed, "avarinitany", lv->vars, lv->avarinitany[bb->rpo]);
+ printed = printbitset(printed, "avarinitall", lv->vars, lv->avarinitall[bb->rpo]);
+ if(printed)
+ print("\n");
+ }
+ print("\n");
+
+ free(uevar);
+ free(varkill);
+ free(avarinit);
+}
+
+// Dumps an array of bitmaps to a symbol as a sequence of uint32 values. The
+// first word dumped is the total number of bitmaps. The second word is the
+// length of the bitmaps. All bitmaps are assumed to be of equal length. The
+// words that are followed are the raw bitmap words. The arr argument is an
+// array of Node*s.
+static void
+twobitwritesymbol(Array *arr, Sym *sym)
+{
+ Bvec *bv;
+ int off, i, j, len;
+ uint32 word;
+
+ len = arraylength(arr);
+ off = 0;
+ off += 4; // number of bitmaps, to fill in later
+ bv = *(Bvec**)arrayget(arr, 0);
+ off = duint32(sym, off, bv->n); // number of bits in each bitmap
+ for(i = 0; i < len; i++) {
+ // bitmap words
+ bv = *(Bvec**)arrayget(arr, i);
+ if(bv == nil)
+ break;
+ for(j = 0; j < bv->n; j += 32) {
+ word = bv->b[j/32];
+ off = duint32(sym, off, word);
+ }
+ }
+ duint32(sym, 0, i); // number of bitmaps
+ ggloblsym(sym, off, 0, 1);
+}
+
+static void
+printprog(Prog *p)
+{
+ while(p != nil) {
+ print("%P\n", p);
+ p = p->link;
+ }
+}
+
+// Entry pointer for liveness analysis. Constructs a complete CFG, solves for
+// the liveness of pointer variables in the function, and emits a runtime data
+// structure read by the garbage collector.
+void
+liveness(Node *fn, Prog *firstp, Sym *argssym, Sym *livesym)
+{
+ Array *cfg, *vars;
+ Liveness *lv;
+ int debugdelta;
+
+ // Change name to dump debugging information only for a specific function.
+ debugdelta = 0;
+ if(strcmp(curfn->nname->sym->name, "!") == 0)
+ debugdelta = 2;
+
+ debuglive += debugdelta;
+ if(debuglive >= 3) {
+ print("liveness: %s\n", curfn->nname->sym->name);
+ printprog(firstp);
+ }
+ checkptxt(fn, firstp);
+
+ // Construct the global liveness state.
+ cfg = newcfg(firstp);
+ if(debuglive >= 3)
+ printcfg(cfg);
+ vars = getvariables(fn);
+ lv = newliveness(fn, firstp, cfg, vars);
+
+ // Run the dataflow framework.
+ livenessprologue(lv);
+ if(debuglive >= 3)
+ livenessprintcfg(lv);
+ livenesssolve(lv);
+ if(debuglive >= 3)
+ livenessprintcfg(lv);
+ livenessepilogue(lv);
+ if(debuglive >= 3)
+ livenessprintcfg(lv);
+ livenesscompact(lv);
+
+ if(debuglive >= 2)
+ livenessprintdebug(lv);
+
+ // Emit the live pointer map data structures
+ twobitwritesymbol(lv->livepointers, livesym);
+ twobitwritesymbol(lv->argslivepointers, argssym);
+
+ // Free everything.
+ freeliveness(lv);
+ arrayfree(vars);
+ freecfg(cfg);
+
+ debuglive -= debugdelta;
+}
diff --git a/src/cmd/gc/popt.c b/src/cmd/gc/popt.c
index 8d7afa011..ea88b94db 100644
--- a/src/cmd/gc/popt.c
+++ b/src/cmd/gc/popt.c
@@ -51,9 +51,14 @@ noreturn(Prog *p)
symlist[2] = pkglookup("throwinit", runtimepkg);
symlist[3] = pkglookup("panic", runtimepkg);
symlist[4] = pkglookup("panicwrap", runtimepkg);
+ symlist[5] = pkglookup("throwreturn", runtimepkg);
+ symlist[6] = pkglookup("selectgo", runtimepkg);
+ symlist[7] = pkglookup("block", runtimepkg);
}
- s = p->to.sym;
+ if(p->to.node == nil)
+ return 0;
+ s = p->to.node->sym;
if(s == S)
return 0;
for(i=0; symlist[i]!=S; i++)
@@ -144,7 +149,13 @@ fixjmp(Prog *firstp)
if(p->opt == dead) {
if(p->link == P && p->as == ARET && last && last->as != ARET) {
// This is the final ARET, and the code so far doesn't have one.
- // Let it stay.
+ // Let it stay. The register allocator assumes that all live code in
+ // the function can be traversed by starting at all the RET instructions
+ // and following predecessor links. If we remove the final RET,
+ // this assumption will not hold in the case of an infinite loop
+ // at the end of a function.
+ // Keep the RET but mark it dead for the liveness analysis.
+ p->mode = 1;
} else {
if(debug['R'] && debug['v'])
print("del %P\n", p);
@@ -489,8 +500,8 @@ struct TempVar
TempFlow *use; // use list, chained through TempFlow.uselink
TempVar *freelink; // next free temp in Type.opt list
TempVar *merge; // merge var with this one
- uint32 start; // smallest Prog.loc in live range
- uint32 end; // largest Prog.loc in live range
+ vlong start; // smallest Prog.pc in live range
+ vlong end; // largest Prog.pc in live range
uchar addr; // address taken - no accurate end
uchar removed; // removed from program
};
@@ -520,10 +531,11 @@ startcmp(const void *va, const void *vb)
static int
canmerge(Node *n)
{
- return n->class == PAUTO && !n->addrtaken && strncmp(n->sym->name, "autotmp", 7) == 0;
+ return n->class == PAUTO && strncmp(n->sym->name, "autotmp", 7) == 0;
}
static void mergewalk(TempVar*, TempFlow*, uint32);
+static void varkillwalk(TempVar*, TempFlow*, uint32);
void
mergetemp(Prog *firstp)
@@ -544,7 +556,7 @@ mergetemp(Prog *firstp)
g = flowstart(firstp, sizeof(TempFlow));
if(g == nil)
return;
-
+
// Build list of all mergeable variables.
nvar = 0;
for(l = curfn->dcl; l != nil; l = l->next)
@@ -640,6 +652,11 @@ mergetemp(Prog *firstp)
gen++;
for(r = v->use; r != nil; r = r->uselink)
mergewalk(v, r, gen);
+ if(v->addr) {
+ gen++;
+ for(r = v->use; r != nil; r = r->uselink)
+ varkillwalk(v, r, gen);
+ }
}
// Sort variables by start.
@@ -659,7 +676,7 @@ mergetemp(Prog *firstp)
nfree = nvar;
for(i=0; i<nvar; i++) {
v = bystart[i];
- if(v->addr || v->removed)
+ if(v->removed)
continue;
// Expire no longer in use.
@@ -672,7 +689,12 @@ mergetemp(Prog *firstp)
t = v->node->type;
for(j=nfree; j<nvar; j++) {
v1 = inuse[j];
- if(eqtype(t, v1->node->type)) {
+ // Require the types to match but also require the addrtaken bits to match.
+ // If a variable's address is taken, that disables registerization for the individual
+ // words of the variable (for example, the base,len,cap of a slice).
+ // We don't want to merge a non-addressed var with an addressed one and
+ // inhibit registerization of the former.
+ if(eqtype(t, v1->node->type) && v->node->addrtaken == v1->node->addrtaken) {
inuse[j] = inuse[nfree++];
if(v1->merge)
v->merge = v1->merge;
@@ -695,7 +717,7 @@ mergetemp(Prog *firstp)
if(Debug) {
print("%S [%d - %d]\n", curfn->nname->sym, nvar, nkill);
for(v=var; v<var+nvar; v++) {
- print("var %#N %T %d-%d", v->node, v->node->type, v->start, v->end);
+ print("var %#N %T %lld-%lld", v->node, v->node->type, v->start, v->end);
if(v->addr)
print(" addr=1");
if(v->removed)
@@ -752,10 +774,10 @@ mergewalk(TempVar *v, TempFlow *r0, uint32 gen)
break;
r1->f.active = gen;
p = r1->f.prog;
- if(v->end < p->loc)
- v->end = p->loc;
+ if(v->end < p->pc)
+ v->end = p->pc;
if(r1 == v->def) {
- v->start = p->loc;
+ v->start = p->pc;
break;
}
}
@@ -765,6 +787,29 @@ mergewalk(TempVar *v, TempFlow *r0, uint32 gen)
mergewalk(v, r2, gen);
}
+static void
+varkillwalk(TempVar *v, TempFlow *r0, uint32 gen)
+{
+ Prog *p;
+ TempFlow *r1, *r;
+
+ for(r1 = r0; r1 != nil; r1 = (TempFlow*)r1->f.s1) {
+ if(r1->f.active == gen)
+ break;
+ r1->f.active = gen;
+ p = r1->f.prog;
+ if(v->end < p->pc)
+ v->end = p->pc;
+ if(v->start > p->pc)
+ v->start = p->pc;
+ if(p->as == ARET || (p->as == AVARKILL && p->to.node == v->node))
+ break;
+ }
+
+ for(r = r0; r != r1; r = (TempFlow*)r->f.s1)
+ varkillwalk(v, (TempFlow*)r->f.s2, gen);
+}
+
// Eliminate redundant nil pointer checks.
//
// The code generation pass emits a CHECKNIL for every possibly nil pointer.
@@ -911,7 +956,7 @@ nilwalkback(NilFlow *rcheck)
static void
nilwalkfwd(NilFlow *rcheck)
{
- NilFlow *r;
+ NilFlow *r, *last;
Prog *p;
ProgInfo info;
@@ -922,6 +967,7 @@ nilwalkfwd(NilFlow *rcheck)
// avoid problems like:
// _ = *x // should panic
// for {} // no writes but infinite loop may be considered visible
+ last = nil;
for(r = (NilFlow*)uniqs(&rcheck->f); r != nil; r = (NilFlow*)uniqs(&r->f)) {
p = r->f.prog;
proginfo(&info, p);
@@ -944,5 +990,12 @@ nilwalkfwd(NilFlow *rcheck)
// Stop if memory write.
if((info.flags & RightWrite) && !regtyp(&p->to))
return;
+ // Stop if we jump backward.
+ // This test is valid because all the NilFlow* are pointers into
+ // a single contiguous array. We will need to add an explicit
+ // numbering when the code is converted to Go.
+ if(last != nil && r <= last)
+ return;
+ last = r;
}
}
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index d6a5b3cce..285bd78a2 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -166,6 +166,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
goto ret;
case OCFUNC:
+ case OVARKILL:
// can't matter
goto ret;
@@ -181,7 +182,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
// x, y := f() becomes BLOCK{CALL f, AS x [SP+0], AS y [SP+n]}
// We don't want to instrument between the statements because it will
// smash the results.
- racewalknode(&n->list->n, &n->ninit, 0, 0);
+ racewalknode(&n->list->n, &n->list->n->ninit, 0, 0);
fini = nil;
racewalklist(n->list->next, &fini);
n->list = concat(n->list, fini);
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
index bd271da38..45aa521b3 100644
--- a/src/cmd/gc/range.c
+++ b/src/cmd/gc/range.c
@@ -111,6 +111,8 @@ walkrange(Node *n)
Node *hb; // hidden bool
Node *a, *v1, *v2; // not hidden aggregate, val 1, 2
Node *fn, *tmp;
+ Node *keyname, *valname;
+ Node *key, *val;
NodeList *body, *init;
Type *th, *t;
int lno;
@@ -120,34 +122,23 @@ walkrange(Node *n)
a = n->right;
lno = setlineno(a);
- if(t->etype == TSTRING && !eqtype(t, types[TSTRING])) {
- a = nod(OCONV, n->right, N);
- a->type = types[TSTRING];
- }
v1 = n->list->n;
v2 = N;
- if(n->list->next)
+ if(n->list->next && !isblank(n->list->next->n))
v2 = n->list->next->n;
// n->list has no meaning anymore, clear it
// to avoid erroneous processing by racewalk.
n->list = nil;
hv2 = N;
- if(v2 == N && t->etype == TARRAY) {
- // will have just one reference to argument.
- // no need to make a potentially expensive copy.
- ha = a;
- } else {
- ha = temp(a->type);
- init = list(init, nod(OAS, ha, a));
- }
-
switch(t->etype) {
default:
fatal("walkrange");
case TARRAY:
+ // orderstmt arranged for a copy of the array/slice variable if needed.
+ ha = a;
hv1 = temp(types[TINT]);
hn = temp(types[TINT]);
hp = nil;
@@ -162,8 +153,7 @@ walkrange(Node *n)
}
n->ntest = nod(OLT, hv1, hn);
- n->nincr = nod(OASOP, hv1, nodintconst(1));
- n->nincr->etype = OADD;
+ n->nincr = nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)));
if(v2 == N)
body = list1(nod(OAS, v1, hv1));
else {
@@ -171,54 +161,70 @@ walkrange(Node *n)
a->list = list(list1(v1), v2);
a->rlist = list(list1(hv1), nod(OIND, hp, N));
body = list1(a);
-
+
+ // Advance pointer as part of increment.
+ // We used to advance the pointer before executing the loop body,
+ // but doing so would make the pointer point past the end of the
+ // array during the final iteration, possibly causing another unrelated
+ // piece of memory not to be garbage collected until the loop finished.
+ // Advancing during the increment ensures that the pointer p only points
+ // pass the end of the array during the final "p++; i++; if(i >= len(x)) break;",
+ // after which p is dead, so it cannot confuse the collector.
tmp = nod(OADD, hp, nodintconst(t->type->width));
tmp->type = hp->type;
tmp->typecheck = 1;
tmp->right->type = types[tptr];
tmp->right->typecheck = 1;
- body = list(body, nod(OAS, hp, tmp));
+ a = nod(OAS, hp, tmp);
+ typecheck(&a, Etop);
+ n->nincr->ninit = list1(a);
}
break;
case TMAP:
- th = typ(TARRAY);
- th->type = ptrto(types[TUINT8]);
- // see ../../pkg/runtime/hashmap.c:/hash_iter
- // Size of hash_iter in # of pointers.
- th->bound = 11;
- hit = temp(th);
+ // orderstmt allocated the iterator for us.
+ // we only use a once, so no copy needed.
+ ha = a;
+ th = hiter(t);
+ hit = n->alloc;
+ hit->type = th;
+ n->left = N;
+ keyname = newname(th->type->sym); // depends on layout of iterator struct. See reflect.c:hiter
+ valname = newname(th->type->down->sym); // ditto
fn = syslook("mapiterinit", 1);
argtype(fn, t->down);
argtype(fn, t->type);
argtype(fn, th);
init = list(init, mkcall1(fn, T, nil, typename(t), ha, nod(OADDR, hit, N)));
- n->ntest = nod(ONE, nod(OINDEX, hit, nodintconst(0)), nodnil());
+ n->ntest = nod(ONE, nod(ODOT, hit, keyname), nodnil());
fn = syslook("mapiternext", 1);
argtype(fn, th);
n->nincr = mkcall1(fn, T, nil, nod(OADDR, hit, N));
+ key = nod(ODOT, hit, keyname);
+ key = nod(OIND, key, N);
if(v2 == N) {
- fn = syslook("mapiter1", 1);
- argtype(fn, th);
- argtype(fn, t->down);
- a = nod(OAS, v1, mkcall1(fn, t->down, nil, nod(OADDR, hit, N)));
+ a = nod(OAS, v1, key);
} else {
- fn = syslook("mapiter2", 1);
- argtype(fn, th);
- argtype(fn, t->down);
- argtype(fn, t->type);
+ val = nod(ODOT, hit, valname);
+ val = nod(OIND, val, N);
a = nod(OAS2, N, N);
a->list = list(list1(v1), v2);
- a->rlist = list1(mkcall1(fn, getoutargx(fn->type), nil, nod(OADDR, hit, N)));
+ a->rlist = list(list1(key), val);
}
body = list1(a);
break;
case TCHAN:
+ // orderstmt arranged for a copy of the channel variable.
+ ha = a;
+ n->ntest = N;
+
hv1 = temp(t->type);
+ if(haspointers(t->type))
+ init = list(init, nod(OAS, hv1, N));
hb = temp(types[TBOOL]);
n->ntest = nod(ONE, hb, nodbool(0));
@@ -231,6 +237,9 @@ walkrange(Node *n)
break;
case TSTRING:
+ // orderstmt arranged for a copy of the string variable.
+ ha = a;
+
ohv1 = temp(types[TINT]);
hv1 = temp(types[TINT]);
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index 0a8aa8d7a..dbb447e4e 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -125,6 +125,8 @@ mapbucket(Type *t)
keytype = t->down;
valtype = t->type;
+ dowidth(keytype);
+ dowidth(valtype);
if(keytype->width > MAXKEYSIZE)
keytype = ptrto(keytype);
if(valtype->width > MAXVALSIZE)
@@ -143,6 +145,11 @@ mapbucket(Type *t)
overflowfield->sym = mal(sizeof(Sym)); // not important but needs to be set to give this type a name
overflowfield->sym->name = "overflow";
offset += widthptr;
+
+ // The keys are padded to the native integer alignment.
+ // This is usually the same as widthptr; the exception (as usual) is nacl/amd64.
+ if(widthreg > widthptr)
+ offset += widthreg - widthptr;
keysfield = typ(TFIELD);
keysfield->type = typ(TARRAY);
@@ -173,6 +180,7 @@ mapbucket(Type *t)
bucket->width = offset;
bucket->local = t->local;
t->bucket = bucket;
+ bucket->map = t;
return bucket;
}
@@ -229,10 +237,89 @@ hmap(Type *t)
h->width = offset;
h->local = t->local;
t->hmap = h;
- h->hmap = t;
+ h->map = t;
return h;
}
+Type*
+hiter(Type *t)
+{
+ int32 n, off;
+ Type *field[7];
+ Type *i;
+
+ if(t->hiter != T)
+ return t->hiter;
+
+ // build a struct:
+ // hash_iter {
+ // key *Key
+ // val *Value
+ // t *MapType
+ // h *Hmap
+ // buckets *Bucket
+ // bptr *Bucket
+ // other [4]uintptr
+ // }
+ // must match ../../pkg/runtime/hashmap.c:hash_iter.
+ field[0] = typ(TFIELD);
+ field[0]->type = ptrto(t->down);
+ field[0]->sym = mal(sizeof(Sym));
+ field[0]->sym->name = "key";
+
+ field[1] = typ(TFIELD);
+ field[1]->type = ptrto(t->type);
+ field[1]->sym = mal(sizeof(Sym));
+ field[1]->sym->name = "val";
+
+ field[2] = typ(TFIELD);
+ field[2]->type = ptrto(types[TUINT8]); // TODO: is there a Type type?
+ field[2]->sym = mal(sizeof(Sym));
+ field[2]->sym->name = "t";
+
+ field[3] = typ(TFIELD);
+ field[3]->type = ptrto(hmap(t));
+ field[3]->sym = mal(sizeof(Sym));
+ field[3]->sym->name = "h";
+
+ field[4] = typ(TFIELD);
+ field[4]->type = ptrto(mapbucket(t));
+ field[4]->sym = mal(sizeof(Sym));
+ field[4]->sym->name = "buckets";
+
+ field[5] = typ(TFIELD);
+ field[5]->type = ptrto(mapbucket(t));
+ field[5]->sym = mal(sizeof(Sym));
+ field[5]->sym->name = "bptr";
+
+ // all other non-pointer fields
+ field[6] = typ(TFIELD);
+ field[6]->type = typ(TARRAY);
+ field[6]->type->type = types[TUINTPTR];
+ field[6]->type->bound = 4;
+ field[6]->type->width = 4 * widthptr;
+ field[6]->sym = mal(sizeof(Sym));
+ field[6]->sym->name = "other";
+
+ // build iterator struct holding the above fields
+ i = typ(TSTRUCT);
+ i->noalg = 1;
+ i->type = field[0];
+ off = 0;
+ for(n = 0; n < 6; n++) {
+ field[n]->down = field[n+1];
+ field[n]->width = off;
+ off += field[n]->type->width;
+ }
+ field[6]->down = T;
+ off += field[6]->type->width;
+ if(off != 10 * widthptr)
+ yyerror("hash_iter size not correct %d %d", off, 10 * widthptr);
+ t->hiter = i;
+ i->map = t;
+ return i;
+}
+
/*
* f is method type, with receiver.
* return function type, receiver as first argument (or not).
@@ -396,9 +483,8 @@ imethods(Type *t)
last->link = a;
last = a;
- // Compiler can only refer to wrappers for
- // named interface types and non-blank methods.
- if(t->sym == S || isblanksym(method))
+ // Compiler can only refer to wrappers for non-blank methods.
+ if(isblanksym(method))
continue;
// NOTE(rsc): Perhaps an oversight that
@@ -620,6 +706,10 @@ haspointers(Type *t)
ret = 1;
break;
}
+ if(t->bound == 0) { // empty array
+ ret = 0;
+ break;
+ }
ret = haspointers(t->type);
break;
case TSTRUCT:
@@ -656,7 +746,7 @@ static int
dcommontype(Sym *s, int ot, Type *t)
{
int i, alg, sizeofAlg;
- Sym *sptr, *algsym;
+ Sym *sptr, *algsym, *zero;
static Sym *algarray;
char *p;
@@ -677,6 +767,18 @@ dcommontype(Sym *s, int ot, Type *t)
else
sptr = weaktypesym(ptrto(t));
+ // All (non-reflect-allocated) Types share the same zero object.
+ // Each place in the compiler where a pointer to the zero object
+ // might be returned by a runtime call (map access return value,
+ // 2-arg type cast) declares the size of the zerovalue it needs.
+ // The linker magically takes the max of all the sizes.
+ zero = pkglookup("zerovalue", runtimepkg);
+
+ // We use size 0 here so we get the pointer to the zero value,
+ // but don't allocate space for the zero value unless we need it.
+ // TODO: how do we get this symbol into bss? We really want
+ // a read-only bss, but I don't think such a thing exists.
+
// ../../pkg/reflect/type.go:/^type.commonType
// actual type structure
// type commonType struct {
@@ -691,6 +793,7 @@ dcommontype(Sym *s, int ot, Type *t)
// string *string
// *extraType
// ptrToThis *Type
+ // zero unsafe.Pointer
// }
ot = duintptr(s, ot, t->width);
ot = duint32(s, ot, typehash(t));
@@ -728,6 +831,7 @@ dcommontype(Sym *s, int ot, Type *t)
ot += widthptr;
ot = dsymptr(s, ot, sptr, 0); // ptrto type
+ ot = dsymptr(s, ot, zero, 0); // ptr to zero value
return ot;
}
@@ -893,7 +997,7 @@ ok:
switch(t->etype) {
default:
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
break;
case TARRAY:
@@ -905,7 +1009,7 @@ ok:
t2->bound = -1; // slice
s2 = dtypesym(t2);
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s1, 0);
ot = dsymptr(s, ot, s2, 0);
ot = duintptr(s, ot, t->bound);
@@ -913,7 +1017,7 @@ ok:
// ../../pkg/runtime/type.go:/SliceType
s1 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s1, 0);
}
break;
@@ -922,7 +1026,7 @@ ok:
// ../../pkg/runtime/type.go:/ChanType
s1 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s1, 0);
ot = duintptr(s, ot, t->chan);
break;
@@ -939,7 +1043,7 @@ ok:
dtypesym(t1->type);
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = duint8(s, ot, isddd);
// two slice headers: in and out.
@@ -971,7 +1075,7 @@ ok:
// ../../pkg/runtime/type.go:/InterfaceType
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
ot = duintxx(s, ot, n, widthint);
ot = duintxx(s, ot, n, widthint);
@@ -990,7 +1094,7 @@ ok:
s3 = dtypesym(mapbucket(t));
s4 = dtypesym(hmap(t));
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s1, 0);
ot = dsymptr(s, ot, s2, 0);
ot = dsymptr(s, ot, s3, 0);
@@ -1007,7 +1111,7 @@ ok:
// ../../pkg/runtime/type.go:/PtrType
s1 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s1, 0);
break;
@@ -1020,7 +1124,7 @@ ok:
n++;
}
ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
+ xt = ot - 3*widthptr;
ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
ot = duintxx(s, ot, n, widthint);
ot = duintxx(s, ot, n, widthint);
@@ -1218,7 +1322,22 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
// NOTE: Any changes here need to be made to reflect.PtrTo as well.
if(*off % widthptr != 0)
fatal("dgcsym1: invalid alignment, %T", t);
- if(!haspointers(t->type) || t->type->etype == TUINT8) {
+
+ // NOTE(rsc): Emitting GC_APTR here for *nonptrtype
+ // (pointer to non-pointer-containing type) means that
+ // we do not record 'nonptrtype' and instead tell the
+ // garbage collector to look up the type of the memory in
+ // type information stored in the heap. In effect we are telling
+ // the collector "we don't trust our information - use yours".
+ // It's not completely clear why we want to do this.
+ // It does have the effect that if you have a *SliceHeader and a *[]int
+ // pointing at the same actual slice header, *SliceHeader will not be
+ // used as an authoritative type for the memory, which is good:
+ // if the collector scanned the memory as type *SliceHeader, it would
+ // see no pointers inside but mark the block as scanned, preventing
+ // the seeing of pointers when we followed the *[]int pointer.
+ // Perhaps that kind of situation is the rationale.
+ if(!haspointers(t->type)) {
ot = duintptr(s, ot, GC_APTR);
ot = duintptr(s, ot, *off);
} else {
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index c8d57ab33..fb5c2a150 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -15,6 +15,7 @@ package PACKAGE
func new(typ *byte) *any
func panicindex()
func panicslice()
+func panicdivide()
func throwreturn()
func throwinit()
func panicwrap(string, string, string)
@@ -36,13 +37,17 @@ func printnl()
func printsp()
func goprintf()
-// filled in by compiler: int n, string, string, ...
-func concatstring()
+func concatstring2(string, string) string
+func concatstring3(string, string, string) string
+func concatstring4(string, string, string, string) string
+func concatstring5(string, string, string, string, string) string
+func concatstrings([]string) string
func cmpstring(string, string) int
func eqstring(string, string) bool
func intstring(int64) string
func slicebytetostring([]byte) string
+func slicebytetostringtmp([]byte) string
func slicerunetostring([]rune) string
func stringtoslicebyte(string) []byte
func stringtoslicerune(string) []rune
@@ -55,8 +60,8 @@ func slicestringcopy(to any, fr any) int
func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte)
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
-func convT2E(typ *byte, elem any) (ret any)
-func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any)
+func convT2E(typ *byte, elem *any) (ret any)
+func convT2I(typ *byte, typ2 *byte, cache **byte, elem *any) (ret any)
// interface type assertions x.(T)
func assertE2E(typ *byte, iface any) (ret any)
@@ -83,29 +88,27 @@ func equal(typ *byte, x1, x2 any) (ret bool)
// *byte is really *runtime.Type
func makemap(mapType *byte, hint int64) (hmap map[any]any)
-func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any)
+func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
func mapaccess1_fast32(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_fast64(mapType *byte, hmap map[any]any, key any) (val *any)
func mapaccess1_faststr(mapType *byte, hmap map[any]any, key any) (val *any)
-func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
+func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
func mapaccess2_fast32(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapaccess2_fast64(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
func mapaccess2_faststr(mapType *byte, hmap map[any]any, key any) (val *any, pres bool)
-func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
+func mapassign1(mapType *byte, hmap map[any]any, key *any, val *any)
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
-func mapdelete(mapType *byte, hmap map[any]any, key any)
+func mapdelete(mapType *byte, hmap map[any]any, key *any)
func mapiternext(hiter *any)
-func mapiter1(hiter *any) (key any)
-func mapiter2(hiter *any) (key any, val any)
// *byte is really *runtime.Type
func makechan(chanType *byte, hint int64) (hchan chan any)
-func chanrecv1(chanType *byte, hchan <-chan any) (elem any)
-func chanrecv2(chanType *byte, hchan <-chan any) (elem any, received bool)
-func chansend1(chanType *byte, hchan chan<- any, elem any)
+func chanrecv1(chanType *byte, hchan <-chan any, elem *any)
+func chanrecv2(chanType *byte, hchan <-chan any, elem *any) bool
+func chansend1(chanType *byte, hchan chan<- any, elem *any)
func closechan(hchan any)
-func selectnbsend(chanType *byte, hchan chan<- any, elem any) bool
+func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool
func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool
diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c
index cd3de8c7b..58a120674 100644
--- a/src/cmd/gc/select.c
+++ b/src/cmd/gc/select.c
@@ -69,6 +69,7 @@ typecheckselect(Node *sel)
n->op = OSELRECV2;
n->left = n->list->n;
n->ntest = n->list->next->n;
+ n->list = nil;
n->right = n->rlist->n;
n->rlist = nil;
break;
@@ -94,7 +95,7 @@ void
walkselect(Node *sel)
{
int lno, i;
- Node *n, *r, *a, *tmp, *var, *cas, *dflt, *ch;
+ Node *n, *r, *a, *var, *cas, *dflt, *ch;
NodeList *l, *init;
if(sel->list == nil && sel->xoffset != 0)
@@ -110,6 +111,8 @@ walkselect(Node *sel)
}
// optimization: one-case select: single op.
+ // TODO(rsc): Reenable optimization once order.c can handle it.
+ // golang.org/issue/7672.
if(i == 1) {
cas = sel->list->n;
setlineno(cas);
@@ -123,32 +126,34 @@ walkselect(Node *sel)
fatal("select %O", n->op);
case OSEND:
- ch = cheapexpr(n->left, &l);
- n->left = ch;
+ // ok already
+ ch = n->left;
break;
case OSELRECV:
- r = n->right;
- ch = cheapexpr(r->left, &l);
- r->left = ch;
-
+ ch = n->right->left;
+ Selrecv1:
if(n->left == N)
- n = r;
- else {
- n = nod(OAS, n->left, r);
- typecheck(&n, Etop);
- }
+ n = n->right;
+ else
+ n->op = OAS;
break;
case OSELRECV2:
- r = n->right;
- ch = cheapexpr(r->left, &l);
- r->left = ch;
-
- a = nod(OAS2, N, N);
- a->list = n->list;
- a->rlist = list1(n->right);
- n = a;
+ ch = n->right->left;
+ if(n->ntest == N)
+ goto Selrecv1;
+ if(n->left == N) {
+ typecheck(&nblank, Erv | Easgn);
+ n->left = nblank;
+ }
+ n->op = OAS2;
+ n->list = list(list1(n->left), n->ntest);
+ n->rlist = list1(n->right);
+ n->right = N;
+ n->left = N;
+ n->ntest = N;
+ n->typecheck = 0;
typecheck(&n, Etop);
break;
}
@@ -166,7 +171,7 @@ walkselect(Node *sel)
goto out;
}
- // introduce temporary variables for OSELRECV where needed.
+ // convert case value arguments to addresses.
// this rewrite is used by both the general code and the next optimization.
for(l=sel->list; l; l=l->next) {
cas = l->n;
@@ -175,58 +180,24 @@ walkselect(Node *sel)
if(n == N)
continue;
switch(n->op) {
+ case OSEND:
+ n->right = nod(OADDR, n->right, N);
+ typecheck(&n->right, Erv);
+ break;
case OSELRECV:
case OSELRECV2:
- ch = n->right->left;
-
- // If we can use the address of the target without
- // violating addressability or order of operations, do so.
- // Otherwise introduce a temporary.
- // Also introduce a temporary for := variables that escape,
- // so that we can delay the heap allocation until the case
- // is selected.
+ if(n->op == OSELRECV2 && n->ntest == N)
+ n->op = OSELRECV;
if(n->op == OSELRECV2) {
- if(n->ntest == N || isblank(n->ntest))
- n->ntest = nodnil();
- else if(n->ntest->op == ONAME &&
- (!n->colas || (n->ntest->class&PHEAP) == 0) &&
- convertop(types[TBOOL], n->ntest->type, nil) == OCONVNOP) {
- n->ntest = nod(OADDR, n->ntest, N);
- n->ntest->etype = 1; // pointer does not escape
- typecheck(&n->ntest, Erv);
- } else {
- tmp = temp(types[TBOOL]);
- a = nod(OADDR, tmp, N);
- a->etype = 1; // pointer does not escape
- typecheck(&a, Erv);
- r = nod(OAS, n->ntest, tmp);
- typecheck(&r, Etop);
- cas->nbody = concat(list1(r), cas->nbody);
- n->ntest = a;
- }
+ n->ntest = nod(OADDR, n->ntest, N);
+ typecheck(&n->ntest, Erv);
}
-
- if(n->left == N || isblank(n->left))
+ if(n->left == N)
n->left = nodnil();
- else if(n->left->op == ONAME &&
- (!n->colas || (n->left->class&PHEAP) == 0) &&
- convertop(ch->type->type, n->left->type, nil) == OCONVNOP) {
+ else {
n->left = nod(OADDR, n->left, N);
- n->left->etype = 1; // pointer does not escape
typecheck(&n->left, Erv);
- } else {
- tmp = temp(ch->type->type);
- a = nod(OADDR, tmp, N);
- a->etype = 1; // pointer does not escape
- typecheck(&a, Erv);
- r = nod(OAS, n->left, tmp);
- typecheck(&r, Etop);
- cas->nbody = concat(list1(r), cas->nbody);
- n->left = a;
- }
-
- cas->nbody = concat(n->ninit, cas->nbody);
- n->ninit = nil;
+ }
break;
}
}
@@ -250,8 +221,8 @@ walkselect(Node *sel)
fatal("select %O", n->op);
case OSEND:
- // if c != nil && selectnbsend(c, v) { body } else { default body }
- ch = cheapexpr(n->left, &r->ninit);
+ // if selectnbsend(c, v) { body } else { default body }
+ ch = n->left;
r->ntest = mkcall1(chanfn("selectnbsend", 2, ch->type),
types[TBOOL], &r->ninit, typename(ch->type), ch, n->right);
break;
@@ -260,7 +231,7 @@ walkselect(Node *sel)
// if c != nil && selectnbrecv(&v, c) { body } else { default body }
r = nod(OIF, N, N);
r->ninit = cas->ninit;
- ch = cheapexpr(n->right->left, &r->ninit);
+ ch = n->right->left;
r->ntest = mkcall1(chanfn("selectnbrecv", 2, ch->type),
types[TBOOL], &r->ninit, typename(ch->type), n->left, ch);
break;
@@ -269,7 +240,7 @@ walkselect(Node *sel)
// if c != nil && selectnbrecv2(&v, c) { body } else { default body }
r = nod(OIF, N, N);
r->ninit = cas->ninit;
- ch = cheapexpr(n->right->left, &r->ninit);
+ ch = n->right->left;
r->ntest = mkcall1(chanfn("selectnbrecv2", 2, ch->type),
types[TBOOL], &r->ninit, typename(ch->type), n->left, n->ntest, ch);
break;
@@ -313,11 +284,6 @@ walkselect(Node *sel)
case OSEND:
// selectsend(sel *byte, hchan *chan any, elem *any) (selected bool);
- n->left = localexpr(safeexpr(n->left, &r->ninit), n->left->type, &r->ninit);
- n->right = localexpr(n->right, n->left->type->type, &r->ninit);
- n->right = nod(OADDR, n->right, N);
- n->right->etype = 1; // pointer does not escape
- typecheck(&n->right, Erv);
r->ntest = mkcall1(chanfn("selectsend", 2, n->left->type), types[TBOOL],
&r->ninit, var, n->left, n->right);
break;
diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c
index 446b1110a..59804cd8d 100644
--- a/src/cmd/gc/sinit.c
+++ b/src/cmd/gc/sinit.c
@@ -286,8 +286,8 @@ staticcopy(Node *l, Node *r, NodeList **out)
if(r->op != ONAME || r->class != PEXTERN || r->sym->pkg != localpkg)
return 0;
- if(r->defn == N) // zeroed
- return 1;
+ if(r->defn == N) // probably zeroed but perhaps supplied externally and of unknown value
+ return 0;
if(r->defn->op != OAS)
return 0;
orig = r;
@@ -354,11 +354,13 @@ staticcopy(Node *l, Node *r, NodeList **out)
else {
ll = nod(OXXX, N, N);
*ll = n1;
+ ll->orig = ll; // completely separate copy
if(!staticassign(ll, e->expr, out)) {
// Requires computation, but we're
// copying someone else's computation.
rr = nod(OXXX, N, N);
*rr = *orig;
+ rr->orig = rr; // completely separate copy
rr->type = ll->type;
rr->xoffset += e->xoffset;
*out = list(*out, nod(OAS, ll, rr));
@@ -378,6 +380,7 @@ staticassign(Node *l, Node *r, NodeList **out)
InitPlan *p;
InitEntry *e;
int i;
+ Strlit *sval;
switch(r->op) {
default:
@@ -426,6 +429,14 @@ staticassign(Node *l, Node *r, NodeList **out)
}
break;
+ case OSTRARRAYBYTE:
+ if(l->class == PEXTERN && r->left->op == OLITERAL) {
+ sval = r->left->val.u.sval;
+ slicebytes(l, sval->s, sval->len);
+ return 1;
+ }
+ break;
+
case OARRAYLIT:
initplan(r);
if(isslice(r->type)) {
@@ -459,6 +470,7 @@ staticassign(Node *l, Node *r, NodeList **out)
else {
a = nod(OXXX, N, N);
*a = n1;
+ a->orig = a; // completely separate copy
if(!staticassign(a, e->expr, out))
*out = list(*out, nod(OAS, a, e->expr));
}
@@ -756,11 +768,24 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
vauto = temp(ptrto(t));
// set auto to point at new temp or heap (3 assign)
- if(n->esc == EscNone) {
- a = nod(OAS, temp(t), N);
- typecheck(&a, Etop);
- *init = list(*init, a); // zero new temp
- a = nod(OADDR, a->left, N);
+ if(n->alloc != N) {
+ // temp allocated during order.c for dddarg
+ n->alloc->type = t;
+ if(vstat == N) {
+ a = nod(OAS, n->alloc, N);
+ typecheck(&a, Etop);
+ *init = list(*init, a); // zero new temp
+ }
+ a = nod(OADDR, n->alloc, N);
+ } else if(n->esc == EscNone) {
+ a = temp(t);
+ if(vstat == N) {
+ a = nod(OAS, temp(t), N);
+ typecheck(&a, Etop);
+ *init = list(*init, a); // zero new temp
+ a = a->left;
+ }
+ a = nod(OADDR, a, N);
} else {
a = nod(ONEW, N, N);
a->list = list1(typenod(t));
@@ -827,7 +852,7 @@ maplit(int ctxt, Node *n, Node *var, NodeList **init)
int nerr;
int64 b;
Type *t, *tk, *tv, *t1;
- Node *vstat, *index, *value;
+ Node *vstat, *index, *value, *key, *val;
Sym *syma, *symb;
USED(ctxt);
@@ -846,7 +871,7 @@ ctxt = 0;
r = l->n;
if(r->op != OKEY)
- fatal("slicelit: rhs not OKEY: %N", r);
+ fatal("maplit: rhs not OKEY: %N", r);
index = r->left;
value = r->right;
@@ -890,7 +915,7 @@ ctxt = 0;
r = l->n;
if(r->op != OKEY)
- fatal("slicelit: rhs not OKEY: %N", r);
+ fatal("maplit: rhs not OKEY: %N", r);
index = r->left;
value = r->right;
@@ -941,8 +966,7 @@ ctxt = 0;
a->ninit = list1(nod(OAS, index, nodintconst(0)));
a->ntest = nod(OLT, index, nodintconst(t->bound));
- a->nincr = nod(OASOP, index, nodintconst(1));
- a->nincr->etype = OADD;
+ a->nincr = nod(OAS, index, nod(OADD, index, nodintconst(1)));
typecheck(&a, Etop);
walkstmt(&a);
@@ -950,25 +974,49 @@ ctxt = 0;
}
// put in dynamic entries one-at-a-time
+ key = nil;
+ val = nil;
for(l=n->list; l; l=l->next) {
r = l->n;
if(r->op != OKEY)
- fatal("slicelit: rhs not OKEY: %N", r);
+ fatal("maplit: rhs not OKEY: %N", r);
index = r->left;
value = r->right;
if(isliteral(index) && isliteral(value))
continue;
+
+ // build list of var[c] = expr.
+ // use temporary so that mapassign1 can have addressable key, val.
+ if(key == nil) {
+ key = temp(var->type->down);
+ val = temp(var->type->type);
+ }
+ a = nod(OAS, key, r->left);
+ typecheck(&a, Etop);
+ walkstmt(&a);
+ *init = list(*init, a);
+ a = nod(OAS, val, r->right);
+ typecheck(&a, Etop);
+ walkstmt(&a);
+ *init = list(*init, a);
- // build list of var[c] = expr
- a = nod(OINDEX, var, r->left);
- a = nod(OAS, a, r->right);
+ a = nod(OAS, nod(OINDEX, var, key), val);
typecheck(&a, Etop);
- walkexpr(&a, init);
+ walkstmt(&a);
+ *init = list(*init, a);
+
if(nerr != nerrors)
break;
-
+ }
+
+ if(key != nil) {
+ a = nod(OVARKILL, key, N);
+ typecheck(&a, Etop);
+ *init = list(*init, a);
+ a = nod(OVARKILL, val, N);
+ typecheck(&a, Etop);
*init = list(*init, a);
}
}
@@ -988,12 +1036,16 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
if(!isptr[t->etype])
fatal("anylit: not ptr");
- r = nod(ONEW, N, N);
- r->typecheck = 1;
- r->type = t;
- r->esc = n->esc;
+ if(n->right != N) {
+ r = nod(OADDR, n->right, N);
+ typecheck(&r, Erv);
+ } else {
+ r = nod(ONEW, N, N);
+ r->typecheck = 1;
+ r->type = t;
+ r->esc = n->esc;
+ }
walkexpr(&r, init);
-
a = nod(OAS, var, r);
typecheck(&a, Etop);
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index bea90b87b..72a9ac20c 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -88,6 +88,7 @@ flusherrors(void)
{
int i;
+ Bflush(&bstdout);
if(nerr == 0)
return;
qsort(err, nerr, sizeof err[0], errcmp);
@@ -258,9 +259,6 @@ fatal(char *fmt, ...)
void
linehist(char *file, int32 off, int relative)
{
- Hist *h;
- char *cp;
-
if(debug['i']) {
if(file != nil) {
if(off < 0)
@@ -274,25 +272,10 @@ linehist(char *file, int32 off, int relative)
print("end of import");
print(" at line %L\n", lexlineno);
}
-
- if(off < 0 && file[0] != '/' && !relative) {
- cp = mal(strlen(file) + strlen(pathname) + 2);
- sprint(cp, "%s/%s", pathname, file);
- file = cp;
- }
-
- h = mal(sizeof(Hist));
- h->name = file;
- h->line = lexlineno;
- h->offset = off;
- h->link = H;
- if(ehist == H) {
- hist = h;
- ehist = h;
- return;
- }
- ehist->link = h;
- ehist = h;
+
+ if(off < 0 && file[0] != '/' && !relative)
+ file = smprint("%s/%s", ctxt->pathname, file);
+ linklinehist(ctxt, lexlineno, file, off);
}
int32
@@ -607,8 +590,6 @@ algtype1(Type *t, Type **bad)
*bad = t;
return ANOEQ;
}
- if(t->bound == 0)
- return AMEM;
a = algtype1(t->type, bad);
if(a == ANOEQ || a == AMEM) {
if(a == ANOEQ && bad)
@@ -1242,8 +1223,10 @@ assignop(Type *src, Type *dst, char **why)
// 2. src and dst have identical underlying types
// and either src or dst is not a named type or
- // both are interface types.
- if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || src->etype == TINTER))
+ // both are empty interface types.
+ // For assignable but different non-empty interface types,
+ // we want to recompute the itab.
+ if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || isnilinter(src)))
return OCONVNOP;
// 3. dst is an interface type and src implements dst.
@@ -1251,13 +1234,16 @@ assignop(Type *src, Type *dst, char **why)
if(implements(src, dst, &missing, &have, &ptr))
return OCONVIFACE;
- // we'll have complained about this method anyway, supress spurious messages.
+ // we'll have complained about this method anyway, suppress spurious messages.
if(have && have->sym == missing->sym && (have->type->broke || missing->type->broke))
return OCONVIFACE;
if(why != nil) {
if(isptrto(src, TINTER))
*why = smprint(":\n\t%T is pointer to interface, not interface", src);
+ else if(have && have->sym == missing->sym && have->nointerface)
+ *why = smprint(":\n\t%T does not implement %T (%S method is marked 'nointerface')",
+ src, dst, missing->sym);
else if(have && have->sym == missing->sym)
*why = smprint(":\n\t%T does not implement %T (wrong type for %S method)\n"
"\t\thave %S%hhT\n\t\twant %S%hhT", src, dst, missing->sym,
@@ -1692,7 +1678,7 @@ typehash(Type *t)
md5reset(&d);
md5write(&d, (uchar*)p, strlen(p));
free(p);
- return md5sum(&d);
+ return md5sum(&d, nil);
}
Type*
@@ -2115,7 +2101,7 @@ cheapexpr(Node *n, NodeList **init)
Node*
localexpr(Node *n, Type *t, NodeList **init)
{
- if(n->op == ONAME && !n->addrtaken &&
+ if(n->op == ONAME && (!n->addrtaken || strncmp(n->sym->name, "autotmp_", 8) == 0) &&
(n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) &&
convertop(n->type, t, nil) == OCONVNOP)
return n;
@@ -2257,6 +2243,7 @@ adddot(Node *n)
int c, d;
typecheck(&n->left, Etype|Erv);
+ n->diag |= n->left->diag;
t = n->left->type;
if(t == T)
goto ret;
@@ -2506,12 +2493,19 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
Type *tpad, *methodrcvr;
int isddd;
Val v;
+ static int linehistdone = 0;
if(0 && debug['r'])
print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
rcvr, method, newnam);
- lineno = 1; // less confusing than end of input
+ lexlineno++;
+ lineno = lexlineno;
+ if (linehistdone == 0) {
+ // All the wrappers can share the same linehist entry.
+ linehist("<autogenerated>", 0, 0);
+ linehistdone = 1;
+ }
dclcontext = PEXTERN;
markdcl();
@@ -2608,8 +2602,10 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
funcbody(fn);
curfn = fn;
- // wrappers where T is anonymous (struct{ NamedType }) can be duplicated.
- if(rcvr->etype == TSTRUCT || isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT)
+ // wrappers where T is anonymous (struct or interface) can be duplicated.
+ if(rcvr->etype == TSTRUCT ||
+ rcvr->etype == TINTER ||
+ isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT)
fn->dupok = 1;
typecheck(&fn, Etop);
typechecklist(fn->nbody, Etop);
@@ -3631,7 +3627,8 @@ ngotype(Node *n)
* only in the last segment of the path, and it makes for happier
* users if we escape that as little as possible.
*
- * If you edit this, edit ../ld/lib.c:/^pathtoprefix copy too.
+ * If you edit this, edit ../ld/lib.c:/^pathtoprefix too.
+ * If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too.
*/
static char*
pathtoprefix(char *s)
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index d6aa021a9..ce0190507 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -317,7 +317,7 @@ casebody(Node *sw, Node *typeswvar)
// botch - shouldn't fall thru declaration
last = stat->end->n;
- if(last->op == OXFALL) {
+ if(last->xoffset == n->xoffset && last->op == OXFALL) {
if(typeswvar) {
setlineno(last);
yyerror("cannot fallthrough in type switch");
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index 31a2f2c5c..c50b2285b 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -310,7 +310,7 @@ typecheck1(Node **np, int top)
int ok, ntop;
Type *t, *tp, *missing, *have, *badtype;
Val v;
- char *why;
+ char *why, *desc, descbuf[64];
n = *np;
@@ -368,7 +368,7 @@ reswitch:
goto ret;
case OPACK:
- yyerror("use of package %S not in selector", n->sym);
+ yyerror("use of package %S without selector", n->sym);
goto error;
case ODDD:
@@ -535,6 +535,19 @@ reswitch:
op = n->etype;
goto arith;
+ case OADDPTR:
+ ok |= Erv;
+ l = typecheck(&n->left, Erv);
+ r = typecheck(&n->right, Erv);
+ if(l->type == T || r->type == T)
+ goto error;
+ if(l->type->etype != tptr)
+ fatal("bad OADDPTR left type %E for %N", l->type->etype, n->left);
+ if(r->type->etype != TUINTPTR)
+ fatal("bad OADDPTR right type %E for %N", r->type->etype, n->right);
+ n->type = types[tptr];
+ goto ret;
+
case OADD:
case OAND:
case OANDAND:
@@ -654,8 +667,20 @@ reswitch:
if(iscmp[n->op]) {
n->etype = n->op;
n->op = OCMPSTR;
- } else if(n->op == OADD)
+ } else if(n->op == OADD) {
+ // create OADDSTR node with list of strings in x + y + z + (w + v) + ...
n->op = OADDSTR;
+ if(l->op == OADDSTR)
+ n->list = l->list;
+ else
+ n->list = list1(l);
+ if(r->op == OADDSTR)
+ n->list = concat(n->list, r->list);
+ else
+ n->list = list(n->list, r);
+ n->left = N;
+ n->right = N;
+ }
}
if(et == TINTER) {
if(l->op == OLITERAL && l->val.ctype == CTNIL) {
@@ -721,8 +746,11 @@ reswitch:
if(n->left->type == T)
goto error;
checklvalue(n->left, "take the address of");
- for(l=n->left; l->op == ODOT; l=l->left)
+ r = outervalue(n->left);
+ for(l = n->left; l != r; l = l->left)
l->addrtaken = 1;
+ if(l->orig != l && l->op == ONAME)
+ fatal("found non-orig name node %N", l);
l->addrtaken = 1;
defaultlit(&n->left, T);
l = n->left;
@@ -864,7 +892,7 @@ reswitch:
goto error;
switch(t->etype) {
default:
- yyerror("invalid operation: %N (index of type %T)", n, t);
+ yyerror("invalid operation: %N (type %T does not support indexing)", n, t);
goto error;
@@ -947,7 +975,7 @@ reswitch:
r = n->right;
if(r->type == T)
goto error;
- r = assignconv(r, l->type->type, "send");
+ n->right = assignconv(r, l->type->type, "send");
// TODO: more aggressive
n->etype = 0;
n->type = T;
@@ -1062,6 +1090,7 @@ reswitch:
goto reswitch;
}
typecheck(&n->left, Erv | Etype | Ecall |(top&Eproc));
+ n->diag |= n->left->diag;
l = n->left;
if(l->op == ONAME && l->etype != 0) {
if(n->isddd && l->etype != OAPPEND)
@@ -1123,7 +1152,11 @@ reswitch:
}
break;
}
- typecheckaste(OCALL, n->left, n->isddd, getinargx(t), n->list, "function argument");
+ if(snprint(descbuf, sizeof descbuf, "argument to %N", n->left) < sizeof descbuf)
+ desc = descbuf;
+ else
+ desc = "function argument";
+ typecheckaste(OCALL, n->left, n->isddd, getinargx(t), n->list, desc);
ok |= Etop;
if(t->outtuple == 0)
goto ret;
@@ -1209,17 +1242,29 @@ reswitch:
case OCOMPLEX:
ok |= Erv;
- if(twoarg(n) < 0)
- goto error;
- l = typecheck(&n->left, Erv | (top & Eiota));
- r = typecheck(&n->right, Erv | (top & Eiota));
- if(l->type == T || r->type == T)
- goto error;
- defaultlit2(&l, &r, 0);
- if(l->type == T || r->type == T)
- goto error;
- n->left = l;
- n->right = r;
+ if(count(n->list) == 1) {
+ typechecklist(n->list, Efnstruct);
+ t = n->list->n->left->type;
+ if(t->outtuple != 2) {
+ yyerror("invalid operation: complex expects two arguments, %N returns %d results", n->list->n, t->outtuple);
+ goto error;
+ }
+ t = n->list->n->type->type;
+ l = t->nname;
+ r = t->down->nname;
+ } else {
+ if(twoarg(n) < 0)
+ goto error;
+ l = typecheck(&n->left, Erv | (top & Eiota));
+ r = typecheck(&n->right, Erv | (top & Eiota));
+ if(l->type == T || r->type == T)
+ goto error;
+ defaultlit2(&l, &r, 0);
+ if(l->type == T || r->type == T)
+ goto error;
+ n->left = l;
+ n->right = r;
+ }
if(!eqtype(l->type, r->type)) {
yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
goto error;
@@ -1298,9 +1343,22 @@ reswitch:
yyerror("missing arguments to append");
goto error;
}
- typechecklist(args, Erv);
+
+ if(count(args) == 1 && !n->isddd)
+ typecheck(&args->n, Erv | Efnstruct);
+ else
+ typechecklist(args, Erv);
+
if((t = args->n->type) == T)
goto error;
+
+ // Unpack multiple-return result before type-checking.
+ if(istype(t, TSTRUCT)) {
+ t = t->type;
+ if(istype(t, TFIELD))
+ t = t->type;
+ }
+
n->type = t;
if(!isslice(t)) {
if(isconst(args->n, CTNIL)) {
@@ -1355,6 +1413,8 @@ reswitch:
goto error;
defaultlit(&n->left, T);
defaultlit(&n->right, T);
+ if(n->left->type == T || n->right->type == T)
+ goto error;
// copy([]byte, string)
if(isslice(n->left->type) && n->right->type->etype == TSTRING) {
@@ -1406,6 +1466,9 @@ reswitch:
}
break;
case OSTRARRAYBYTE:
+ // do not use stringtoarraylit.
+ // generated code and compiler memory footprint is better without it.
+ break;
case OSTRARRAYRUNE:
if(n->left->op == OLITERAL)
stringtoarraylit(&n);
@@ -1621,6 +1684,7 @@ reswitch:
case OGOTO:
case OLABEL:
case OXFALL:
+ case OVARKILL:
ok |= Etop;
goto ret;
@@ -2116,6 +2180,31 @@ nokeys(NodeList *l)
return 1;
}
+static int
+hasddd(Type *t)
+{
+ Type *tl;
+
+ for(tl=t->type; tl; tl=tl->down) {
+ if(tl->isddd)
+ return 1;
+ }
+ return 0;
+}
+
+static int
+downcount(Type *t)
+{
+ Type *tl;
+ int n;
+
+ n = 0;
+ for(tl=t->type; tl; tl=tl->down) {
+ n++;
+ }
+ return n;
+}
+
/*
* typecheck assignment: type list = expression list
*/
@@ -2126,14 +2215,25 @@ typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *
Node *n;
int lno;
char *why;
+ int n1, n2;
lno = lineno;
if(tstruct->broke)
goto out;
+ n = N;
if(nl != nil && nl->next == nil && (n = nl->n)->type != T)
if(n->type->etype == TSTRUCT && n->type->funarg) {
+ if(!hasddd(tstruct)) {
+ n1 = downcount(tstruct);
+ n2 = downcount(n->type);
+ if(n2 > n1)
+ goto toomany;
+ if(n2 < n1)
+ goto notenough;
+ }
+
tn = n->type->type;
for(tl=tstruct->type; tl; tl=tl->down) {
if(tl->isddd) {
@@ -2162,6 +2262,26 @@ typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *
goto out;
}
+ n1 = downcount(tstruct);
+ n2 = count(nl);
+ if(!hasddd(tstruct)) {
+ if(n2 > n1)
+ goto toomany;
+ if(n2 < n1)
+ goto notenough;
+ }
+ else {
+ if(!isddd) {
+ if(n2 < n1-1)
+ goto notenough;
+ } else {
+ if(n2 > n1)
+ goto toomany;
+ if(n2 < n1)
+ goto notenough;
+ }
+ }
+
for(tl=tstruct->type; tl; tl=tl->down) {
t = tl->type;
if(tl->isddd) {
@@ -2206,10 +2326,14 @@ out:
return;
notenough:
- if(call != N)
- yyerror("not enough arguments in call to %N", call);
- else
- yyerror("not enough arguments to %O", op);
+ if(n == N || !n->diag) {
+ if(call != N)
+ yyerror("not enough arguments in call to %N", call);
+ else
+ yyerror("not enough arguments to %O", op);
+ if(n != N)
+ n->diag = 1;
+ }
goto out;
toomany:
@@ -2252,10 +2376,13 @@ keydup(Node *n, Node *hash[], ulong nhash)
ulong b;
double d;
int i;
- Node *a;
+ Node *a, *orign;
Node cmp;
char *s;
+ orign = n;
+ if(n->op == OCONVIFACE)
+ n = n->left;
evconst(n);
if(n->op != OLITERAL)
return; // we dont check variables
@@ -2288,17 +2415,25 @@ keydup(Node *n, Node *hash[], ulong nhash)
for(a=hash[h]; a!=N; a=a->ntest) {
cmp.op = OEQ;
cmp.left = n;
- cmp.right = a;
- evconst(&cmp);
- b = cmp.val.u.bval;
+ b = 0;
+ if(a->op == OCONVIFACE && orign->op == OCONVIFACE) {
+ if(eqtype(a->left->type, n->type)) {
+ cmp.right = a->left;
+ evconst(&cmp);
+ b = cmp.val.u.bval;
+ }
+ } else if(eqtype(a->type, n->type)) {
+ cmp.right = a;
+ evconst(&cmp);
+ b = cmp.val.u.bval;
+ }
if(b) {
- // too lazy to print the literal
yyerror("duplicate key %N in map literal", n);
return;
}
}
- n->ntest = hash[h];
- hash[h] = n;
+ orign->ntest = hash[h];
+ hash[h] = orign;
}
static void
@@ -2486,8 +2621,9 @@ typecheckcomplit(Node **np)
typecheck(&l->left, Erv);
evconst(l->left);
i = nonnegconst(l->left);
- if(i < 0) {
+ if(i < 0 && !l->left->diag) {
yyerror("array index must be non-negative integer constant");
+ l->left->diag = 1;
i = -(1<<30); // stay negative for a while
}
if(i >= 0)
@@ -2497,7 +2633,7 @@ typecheckcomplit(Node **np)
len = i;
if(t->bound >= 0 && len > t->bound) {
setlineno(l);
- yyerror("array index %d out of bounds [0:%d]", len, t->bound);
+ yyerror("array index %lld out of bounds [0:%lld]", len-1, t->bound);
t->bound = -1; // no more errors
}
}
@@ -2680,6 +2816,11 @@ checkassign(Node *n)
n->etype = 1;
return;
}
+
+ // have already complained about n being undefined
+ if(n->op == ONONAME)
+ return;
+
yyerror("cannot assign to %N", n);
}
@@ -2804,7 +2945,7 @@ typecheckas2(Node *n)
n->op = OAS2FUNC;
t = structfirst(&s, &r->type);
for(ll=n->list; ll; ll=ll->next) {
- if(ll->n->type != T)
+ if(t->type != T && ll->n->type != T)
checkassignto(t->type, ll->n);
if(ll->n->defn == n && ll->n->ntype == N)
ll->n->type = t->type;
@@ -3130,7 +3271,10 @@ typecheckdef(Node *n)
goto ret;
}
if(e->type != T && e->op != OLITERAL || !isgoconst(e)) {
- yyerror("const initializer %N is not a constant", e);
+ if(!e->diag) {
+ yyerror("const initializer %N is not a constant", e);
+ e->diag = 1;
+ }
goto ret;
}
t = n->type;
@@ -3220,29 +3364,38 @@ static int
checkmake(Type *t, char *arg, Node *n)
{
if(n->op == OLITERAL) {
- n->val = toint(n->val);
- if(mpcmpfixc(n->val.u.xval, 0) < 0) {
- yyerror("negative %s argument in make(%T)", arg, t);
- return -1;
- }
- if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) {
- yyerror("%s argument too large in make(%T)", arg, t);
- return -1;
+ switch(n->val.ctype) {
+ case CTINT:
+ case CTRUNE:
+ case CTFLT:
+ case CTCPLX:
+ n->val = toint(n->val);
+ if(mpcmpfixc(n->val.u.xval, 0) < 0) {
+ yyerror("negative %s argument in make(%T)", arg, t);
+ return -1;
+ }
+ if(mpcmpfixfix(n->val.u.xval, maxintval[TINT]) > 0) {
+ yyerror("%s argument too large in make(%T)", arg, t);
+ return -1;
+ }
+
+ // Delay defaultlit until after we've checked range, to avoid
+ // a redundant "constant NNN overflows int" error.
+ defaultlit(&n, types[TINT]);
+ return 0;
+ default:
+ break;
}
-
- // Delay defaultlit until after we've checked range, to avoid
- // a redundant "constant NNN overflows int" error.
- defaultlit(&n, types[TINT]);
- return 0;
}
-
- // Defaultlit still necessary for non-constant: n might be 1<<k.
- defaultlit(&n, types[TINT]);
- if(!isint[n->type->etype]) {
+ if(!isint[n->type->etype] && n->type->etype != TIDEAL) {
yyerror("non-integer %s argument in make(%T) - %T", arg, t, n->type);
return -1;
}
+
+ // Defaultlit still necessary for non-constant: n might be 1<<k.
+ defaultlit(&n, types[TINT]);
+
return 0;
}
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 66409d530..1cb25512e 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -21,7 +21,7 @@ static NodeList* reorder3(NodeList*);
static Node* addstr(Node*, NodeList**);
static Node* appendslice(Node*, NodeList**);
static Node* append(Node*, NodeList**);
-static Node* copyany(Node*, NodeList**);
+static Node* copyany(Node*, NodeList**, int);
static Node* sliceany(Node*, NodeList**);
static void walkcompare(Node**, NodeList**);
static void walkrotate(Node**);
@@ -163,7 +163,6 @@ walkstmt(Node **np)
case OCALLFUNC:
case ODELETE:
case OSEND:
- case ORECV:
case OPRINT:
case OPRINTN:
case OPANIC:
@@ -179,6 +178,21 @@ walkstmt(Node **np)
n->op = OEMPTY; // don't leave plain values as statements.
break;
+ case ORECV:
+ // special case for a receive where we throw away
+ // the value received.
+ if(n->typecheck == 0)
+ fatal("missing typecheck: %+N", n);
+ init = n->ninit;
+ n->ninit = nil;
+
+ walkexpr(&n->left, &init);
+ n = mkcall1(chanfn("chanrecv1", 2, n->left->type), T, &init, typename(n->left->type), n->left, nodnil());
+ walkexpr(&n, &init);
+
+ addinit(&n, init);
+ break;
+
case OBREAK:
case ODCL:
case OCONTINUE:
@@ -188,6 +202,7 @@ walkstmt(Node **np)
case ODCLCONST:
case ODCLTYPE:
case OCHECKNIL:
+ case OVARKILL:
break;
case OBLOCK:
@@ -209,6 +224,9 @@ walkstmt(Node **np)
walkexprlist(n->left->list, &n->ninit);
n->left = walkprint(n->left, &n->ninit, 1);
break;
+ case OCOPY:
+ n->left = copyany(n->left, &n->ninit, 1);
+ break;
default:
walkexpr(&n->left, &n->ninit);
break;
@@ -240,6 +258,9 @@ walkstmt(Node **np)
walkexprlist(n->left->list, &n->ninit);
n->left = walkprint(n->left, &n->ninit, 1);
break;
+ case OCOPY:
+ n->left = copyany(n->left, &n->ninit, 1);
+ break;
default:
walkexpr(&n->left, &n->ninit);
break;
@@ -341,7 +362,8 @@ void
walkexpr(Node **np, NodeList **init)
{
Node *r, *l, *var, *a;
- NodeList *ll, *lr, *lpost;
+ Node *map, *key;
+ NodeList *ll, *lr;
Type *t;
int et, old_safemode;
int64 v;
@@ -455,7 +477,6 @@ walkexpr(Node **np, NodeList **init)
case ORSH:
walkexpr(&n->left, init);
walkexpr(&n->right, init);
- shiftwalked:
t = n->left->type;
n->bounded = bounded(n->right, 8*t->width);
if(debug['m'] && n->etype && !isconst(n->right, CTINT))
@@ -472,6 +493,11 @@ walkexpr(Node **np, NodeList **init)
case OADD:
case OCOMPLEX:
case OLROT:
+ // Use results from call expression as arguments for complex.
+ if(n->op == OCOMPLEX && n->left == N && n->right == N) {
+ n->left = n->list->n;
+ n->right = n->list->next->n;
+ }
walkexpr(&n->left, init);
walkexpr(&n->right, init);
goto ret;
@@ -576,13 +602,32 @@ walkexpr(Node **np, NodeList **init)
case OAS:
*init = concat(*init, n->ninit);
n->ninit = nil;
+
walkexpr(&n->left, init);
n->left = safeexpr(n->left, init);
if(oaslit(n, init))
goto ret;
- walkexpr(&n->right, init);
+ if(n->right == N)
+ goto ret;
+
+ switch(n->right->op) {
+ default:
+ walkexpr(&n->right, init);
+ break;
+
+ case ORECV:
+ // x = <-c; n->left is x, n->right->left is c.
+ // orderstmt made sure x is addressable.
+ walkexpr(&n->right->left, init);
+ n1 = nod(OADDR, n->left, N);
+ r = n->right->left; // the channel
+ n = mkcall1(chanfn("chanrecv1", 2, r->type), T, init, typename(r->type), r, n1);
+ walkexpr(&n, init);
+ goto ret;
+ }
+
if(n->left != N && n->right != N) {
r = convas(nod(OAS, n->left, n->right), init);
r->dodata = n->dodata;
@@ -602,53 +647,35 @@ walkexpr(Node **np, NodeList **init)
goto ret;
case OAS2FUNC:
- as2func:
// a,b,... = fn()
*init = concat(*init, n->ninit);
n->ninit = nil;
r = n->rlist->n;
walkexprlistsafe(n->list, init);
walkexpr(&r, init);
- l = n->list->n;
-
- // all the really hard stuff - explicit function calls and so on -
- // is gone, but map assignments remain.
- // if there are map assignments here, assign via
- // temporaries, because ascompatet assumes
- // the targets can be addressed without function calls
- // and map index has an implicit one.
- lpost = nil;
- if(l->op == OINDEXMAP) {
- var = temp(l->type);
- n->list->n = var;
- a = nod(OAS, l, var);
- typecheck(&a, Etop);
- lpost = list(lpost, a);
- }
- l = n->list->next->n;
- if(l->op == OINDEXMAP) {
- var = temp(l->type);
- n->list->next->n = var;
- a = nod(OAS, l, var);
- typecheck(&a, Etop);
- lpost = list(lpost, a);
- }
+
ll = ascompatet(n->op, n->list, &r->type, 0, init);
- walkexprlist(lpost, init);
- n = liststmt(concat(concat(list1(r), ll), lpost));
+ n = liststmt(concat(list1(r), ll));
goto ret;
case OAS2RECV:
+ // x, y = <-c
+ // orderstmt made sure x is addressable.
*init = concat(*init, n->ninit);
n->ninit = nil;
r = n->rlist->n;
walkexprlistsafe(n->list, init);
walkexpr(&r->left, init);
+ if(isblank(n->list->n))
+ n1 = nodnil();
+ else
+ n1 = nod(OADDR, n->list->n, N);
+ n1->etype = 1; // addr does not escape
fn = chanfn("chanrecv2", 2, r->left->type);
- r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left);
- n->rlist->n = r;
- n->op = OAS2FUNC;
- goto as2func;
+ r = mkcall1(fn, types[TBOOL], init, typename(r->left->type), r->left, n1);
+ n = nod(OAS, n->list->next->n, r);
+ typecheck(&n, Etop);
+ goto ret;
case OAS2MAPR:
// a,b = m[i];
@@ -657,6 +684,7 @@ walkexpr(Node **np, NodeList **init)
r = n->rlist->n;
walkexprlistsafe(n->list, init);
walkexpr(&r->left, init);
+ walkexpr(&r->right, init);
t = r->left->type;
p = nil;
if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
@@ -675,41 +703,50 @@ walkexpr(Node **np, NodeList **init)
}
}
if(p != nil) {
- // from:
- // a,b = m[i]
- // to:
- // var,b = mapaccess2_fast*(t, m, i)
- // a = *var
- a = n->list->n;
- var = temp(ptrto(t->type));
- var->typecheck = 1;
-
- fn = mapfn(p, t);
- r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right);
- n->rlist = list1(r);
- n->op = OAS2FUNC;
- n->list->n = var;
- walkexpr(&n, init);
- *init = list(*init, n);
-
- n = nod(OAS, a, nod(OIND, var, N));
- typecheck(&n, Etop);
- walkexpr(&n, init);
- goto ret;
- }
- fn = mapfn("mapaccess2", t);
- r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, r->right);
+ // fast versions take key by value
+ key = r->right;
+ } else {
+ // standard version takes key by reference
+ // orderexpr made sure key is addressable.
+ key = nod(OADDR, r->right, N);
+ p = "mapaccess2";
+ }
+
+ // from:
+ // a,b = m[i]
+ // to:
+ // var,b = mapaccess2*(t, m, i)
+ // a = *var
+ a = n->list->n;
+ var = temp(ptrto(t->type));
+ var->typecheck = 1;
+ fn = mapfn(p, t);
+ r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key);
n->rlist = list1(r);
n->op = OAS2FUNC;
- goto as2func;
+ n->list->n = var;
+ walkexpr(&n, init);
+ *init = list(*init, n);
+ n = nod(OAS, a, nod(OIND, var, N));
+ typecheck(&n, Etop);
+ walkexpr(&n, init);
+ // mapaccess needs a zero value to be at least this big.
+ if(zerosize < t->type->width)
+ zerosize = t->type->width;
+ // TODO: ptr is always non-nil, so disable nil check for this OIND op.
+ goto ret;
case ODELETE:
*init = concat(*init, n->ninit);
n->ninit = nil;
- l = n->list->n;
- r = n->list->next->n;
- t = l->type;
- n = mkcall1(mapfndel("mapdelete", t), t->down, init, typename(t), l, r);
+ map = n->list->n;
+ key = n->list->next->n;
+ walkexpr(&map, init);
+ walkexpr(&key, init);
+ // orderstmt made sure key is addressable.
+ key = nod(OADDR, key, N);
+ t = map->type;
+ n = mkcall1(mapfndel("mapdelete", t), T, init, typename(t), map, key);
goto ret;
case OAS2DOTTYPE:
@@ -872,7 +909,20 @@ walkexpr(Node **np, NodeList **init)
goto ret;
}
}
- ll = list(ll, n->left);
+ if(isinter(n->left->type)) {
+ ll = list(ll, n->left);
+ } else {
+ // regular types are passed by reference to avoid C vararg calls
+ // orderexpr arranged for n->left to be a temporary for all
+ // the conversions it could see. comparison of an interface
+ // with a non-interface, especially in a switch on interface value
+ // with non-interface cases, is not visible to orderstmt, so we
+ // have to fall back on allocating a temp here.
+ if(islvalue(n->left))
+ ll = list(ll, nod(OADDR, n->left, N));
+ else
+ ll = list(ll, nod(OADDR, copyexpr(n->left, n->left->type, init), N));
+ }
argtype(fn, n->left->type);
argtype(fn, n->type);
dowidth(fn->type);
@@ -909,51 +959,6 @@ walkexpr(Node **np, NodeList **init)
walkexpr(&n->left, init);
goto ret;
- case OASOP:
- if(n->etype == OANDNOT) {
- n->etype = OAND;
- n->right = nod(OCOM, n->right, N);
- typecheck(&n->right, Erv);
- }
- n->left = safeexpr(n->left, init);
- walkexpr(&n->left, init);
- l = n->left;
- walkexpr(&n->right, init);
-
- /*
- * on 32-bit arch, rewrite 64-bit ops into l = l op r.
- * on 386, rewrite float ops into l = l op r.
- * everywhere, rewrite map ops into l = l op r.
- * everywhere, rewrite string += into l = l op r.
- * everywhere, rewrite integer/complex /= into l = l op r.
- * TODO(rsc): Maybe this rewrite should be done always?
- */
- et = n->left->type->etype;
- if((widthptr == 4 && (et == TUINT64 || et == TINT64)) ||
- (thechar == '8' && isfloat[et]) ||
- l->op == OINDEXMAP ||
- et == TSTRING ||
- (!isfloat[et] && n->etype == ODIV) ||
- n->etype == OMOD) {
- l = safeexpr(n->left, init);
- a = l;
- if(a->op == OINDEXMAP) {
- // map index has "lhs" bit set in a->etype.
- // make a copy so we can clear it on the rhs.
- a = nod(OXXX, N, N);
- *a = *l;
- a->etype = 0;
- }
- r = nod(OAS, l, nod(n->etype, a, n->right));
- typecheck(&r, Etop);
- walkexpr(&r, init);
- n = r;
- goto ret;
- }
- if(n->etype == OLSH || n->etype == ORSH)
- goto shiftwalked;
- goto ret;
-
case OANDNOT:
walkexpr(&n->left, init);
n->op = OAND;
@@ -998,7 +1003,7 @@ walkexpr(Node **np, NodeList **init)
switch(n->op) {
case OMOD:
case ODIV:
- if(widthptr > 4 || (et != TUINT64 && et != TINT64))
+ if(widthreg >= 8 || (et != TUINT64 && et != TINT64))
goto ret;
if(et == TINT64)
strcpy(namebuf, "int64");
@@ -1063,6 +1068,8 @@ walkexpr(Node **np, NodeList **init)
case OINDEXMAP:
if(n->etype == 1)
goto ret;
+ walkexpr(&n->left, init);
+ walkexpr(&n->right, init);
t = n->left->type;
p = nil;
@@ -1082,23 +1089,25 @@ walkexpr(Node **np, NodeList **init)
}
}
if(p != nil) {
- // use fast version. The fast versions return a pointer to the value - we need
- // to dereference it to get the result.
- n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, n->right);
- n = nod(OIND, n, N);
- n->type = t->type;
- n->typecheck = 1;
+ // fast versions take key by value
+ key = n->right;
} else {
- // no fast version for this key
- n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right);
- }
+ // standard version takes key by reference.
+ // orderexpr made sure key is addressable.
+ key = nod(OADDR, n->right, N);
+ p = "mapaccess1";
+ }
+ n = mkcall1(mapfn(p, t), ptrto(t->type), init, typename(t), n->left, key);
+ n = nod(OIND, n, N);
+ n->type = t->type;
+ n->typecheck = 1;
+ // mapaccess needs a zero value to be at least this big.
+ if(zerosize < t->type->width)
+ zerosize = t->type->width;
goto ret;
case ORECV:
- walkexpr(&n->left, init);
- walkexpr(&n->right, init);
- n = mkcall1(chanfn("chanrecv1", 2, n->left->type), n->type, init, typename(n->left->type), n->left);
- goto ret;
+ fatal("walkexpr ORECV"); // should see inside OAS only
case OSLICE:
if(n->right != N && n->right->left == N && n->right->right == N) { // noop
@@ -1182,9 +1191,10 @@ walkexpr(Node **np, NodeList **init)
// s + "badgerbadgerbadger" == "badgerbadgerbadger"
if((n->etype == OEQ || n->etype == ONE) &&
isconst(n->right, CTSTR) &&
- n->left->op == OADDSTR && isconst(n->left->right, CTSTR) &&
- cmpslit(n->right, n->left->right) == 0) {
- r = nod(n->etype, nod(OLEN, n->left->left, N), nodintconst(0));
+ n->left->op == OADDSTR && count(n->left->list) == 2 &&
+ isconst(n->left->list->next->n, CTSTR) &&
+ cmpslit(n->right, n->left->list->next->n) == 0) {
+ r = nod(n->etype, nod(OLEN, n->left->list->n, N), nodintconst(0));
typecheck(&r, Erv);
walkexpr(&r, init);
r->type = n->type;
@@ -1238,19 +1248,7 @@ walkexpr(Node **np, NodeList **init)
goto ret;
case OCOPY:
- if(flag_race) {
- if(n->right->type->etype == TSTRING)
- fn = syslook("slicestringcopy", 1);
- else
- fn = syslook("copy", 1);
- argtype(fn, n->left->type);
- argtype(fn, n->right->type);
- n = mkcall1(fn, n->type, init,
- n->left, n->right,
- nodintconst(n->left->type->type->width));
- goto ret;
- }
- n = copyany(n, init);
+ n = copyany(n, init, flag_race);
goto ret;
case OCLOSE:
@@ -1321,6 +1319,11 @@ walkexpr(Node **np, NodeList **init)
n = mkcall("slicebytetostring", n->type, init, n->left);
goto ret;
+ case OARRAYBYTESTRTMP:
+ // slicebytetostringtmp([]byte) string;
+ n = mkcall("slicebytetostringtmp", n->type, init, n->left);
+ goto ret;
+
case OARRAYRUNESTR:
// slicerunetostring([]rune) string;
n = mkcall("slicerunetostring", n->type, init, n->left);
@@ -1368,13 +1371,18 @@ walkexpr(Node **np, NodeList **init)
case OMAPLIT:
case OSTRUCTLIT:
case OPTRLIT:
+ // XXX TODO do we need to clear var?
var = temp(n->type);
anylit(0, n, var, init);
n = var;
goto ret;
case OSEND:
- n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n->right);
+ n1 = n->right;
+ n1 = assignconv(n1, n->left->type->type, "chan send");
+ walkexpr(&n1, init);
+ n1 = nod(OADDR, n1, N);
+ n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n1);
goto ret;
case OCLOSURE:
@@ -1534,11 +1542,16 @@ ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
* package all the arguments that match a ... T parameter into a []T.
*/
static NodeList*
-mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, int esc)
+mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, Node *ddd)
{
Node *a, *n;
Type *tslice;
-
+ int esc;
+
+ esc = EscUnknown;
+ if(ddd != nil)
+ esc = ddd->esc;
+
tslice = typ(TARRAY);
tslice->type = l->type->type;
tslice->bound = -1;
@@ -1548,6 +1561,8 @@ mkdotargslice(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init, int
n->type = tslice;
} else {
n = nod(OCOMPLIT, N, typenod(tslice));
+ if(ddd != nil)
+ n->alloc = ddd->alloc; // temporary to use
n->list = lr0;
n->esc = esc;
typecheck(&n, Erv);
@@ -1619,7 +1634,6 @@ dumpnodetypes(NodeList *l, char *what)
static NodeList*
ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeList **init)
{
- int esc;
Type *l, *ll;
Node *r, *a;
NodeList *nn, *lr0, *alist;
@@ -1638,7 +1652,8 @@ ascompatte(int op, Node *call, int isddd, Type **nl, NodeList *lr, int fp, NodeL
// optimization - can do block copy
if(eqtypenoname(r->type, *nl)) {
a = nodarg(*nl, fp);
- a->type = r->type;
+ r = nod(OCONVNOP, r, N);
+ r->type = a->type;
nn = list1(convas(nod(OAS, a, r), init));
goto ret;
}
@@ -1682,10 +1697,7 @@ loop:
// normal case -- make a slice of all
// remaining arguments and pass it to
// the ddd parameter.
- esc = EscUnknown;
- if(call->right)
- esc = call->right->esc;
- nn = mkdotargslice(lr, nn, l, fp, init, esc);
+ nn = mkdotargslice(lr, nn, l, fp, init, call->right);
goto ret;
}
@@ -1911,6 +1923,7 @@ static Node*
convas(Node *n, NodeList **init)
{
Type *lt, *rt;
+ Node *map, *key, *val;
if(n->op != OAS)
fatal("convas: not OAS %O", n->op);
@@ -1931,9 +1944,17 @@ convas(Node *n, NodeList **init)
}
if(n->left->op == OINDEXMAP) {
- n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
- typename(n->left->left->type),
- n->left->left, n->left->right, n->right);
+ map = n->left->left;
+ key = n->left->right;
+ val = n->right;
+ walkexpr(&map, init);
+ walkexpr(&key, init);
+ walkexpr(&val, init);
+ // orderexpr made sure key and val are addressable.
+ key = nod(OADDR, key, N);
+ val = nod(OADDR, val, N);
+ n = mkcall1(mapfn("mapassign1", map->type), T, init,
+ typename(map->type), map, key, val);
goto out;
}
@@ -2101,7 +2122,7 @@ reorder3save(Node **np, NodeList *all, NodeList *stop, NodeList **early)
* what's the outer value that a write to n affects?
* outer value means containing struct or array.
*/
-static Node*
+Node*
outervalue(Node *n)
{
for(;;) {
@@ -2320,7 +2341,7 @@ paramstoheap(Type **argin, int out)
nn = nil;
for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
v = t->nname;
- if(v && v->sym && v->sym->name[0] == '~')
+ if(v && v->sym && v->sym->name[0] == '~' && v->sym->name[1] == 'r') // unnamed result
v = N;
// In precisestack mode, the garbage collector assumes results
// are always live, so zero them always.
@@ -2493,33 +2514,38 @@ mapfndel(char *name, Type *t)
static Node*
addstr(Node *n, NodeList **init)
{
- Node *r, *cat, *typstr;
- NodeList *in, *args;
- int i, count;
-
- count = 0;
- for(r=n; r->op == OADDSTR; r=r->left)
- count++; // r->right
- count++; // r
-
- // prepare call of runtime.catstring of type int, string, string, string
- // with as many strings as we have.
- cat = syslook("concatstring", 1);
- cat->type = T;
- cat->ntype = nod(OTFUNC, N, N);
- in = list1(nod(ODCLFIELD, N, typenod(types[TINT]))); // count
- typstr = typenod(types[TSTRING]);
- for(i=0; i<count; i++)
- in = list(in, nod(ODCLFIELD, N, typstr));
- cat->ntype->list = in;
- cat->ntype->rlist = list1(nod(ODCLFIELD, N, typstr));
+ Node *r, *cat, *slice;
+ NodeList *args, *l;
+ int c;
+ Type *t;
+
+ // orderexpr rewrote OADDSTR to have a list of strings.
+ c = count(n->list);
+ if(c < 2)
+ yyerror("addstr count %d too small", c);
+ // build list of string arguments
args = nil;
- for(r=n; r->op == OADDSTR; r=r->left)
- args = concat(list1(conv(r->right, types[TSTRING])), args);
- args = concat(list1(conv(r, types[TSTRING])), args);
- args = concat(list1(nodintconst(count)), args);
+ for(l=n->list; l != nil; l=l->next)
+ args = list(args, conv(l->n, types[TSTRING]));
+ if(c <= 5) {
+ // small numbers of strings use direct runtime helpers.
+ // note: orderexpr knows this cutoff too.
+ snprint(namebuf, sizeof(namebuf), "concatstring%d", c);
+ } else {
+ // large numbers of strings are passed to the runtime as a slice.
+ strcpy(namebuf, "concatstrings");
+ t = typ(TARRAY);
+ t->type = types[TSTRING];
+ t->bound = -1;
+ slice = nod(OCOMPLIT, N, typenod(t));
+ slice->alloc = n->alloc;
+ slice->list = args;
+ slice->esc = EscNone;
+ args = list1(slice);
+ }
+ cat = syslook(namebuf, 1);
r = nod(OCALL, cat, N);
r->list = args;
typecheck(&r, Erv);
@@ -2597,9 +2623,10 @@ appendslice(Node *n, NodeList **init)
fn = syslook("copy", 1);
argtype(fn, l1->type);
argtype(fn, l2->type);
- l = list(l, mkcall1(fn, types[TINT], init,
+ nt = mkcall1(fn, types[TINT], &l,
nptr1, nptr2,
- nodintconst(s->type->type->width)));
+ nodintconst(s->type->type->width));
+ l = list(l, nt);
} else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 = nod(OINDEX, s, nod(OLEN, l1, N));
@@ -2614,7 +2641,8 @@ appendslice(Node *n, NodeList **init)
nwid = cheapexpr(conv(nod(OLEN, l2, N), types[TUINTPTR]), &l);
nwid = nod(OMUL, nwid, nodintconst(s->type->type->width));
- l = list(l, mkcall1(fn, T, init, nptr1, nptr2, nwid));
+ nt = mkcall1(fn, T, &l, nptr1, nptr2, nwid);
+ l = list(l, nt);
}
// s = s[:len(l1)+len(l2)]
@@ -2660,6 +2688,10 @@ append(Node *n, NodeList **init)
l->n = cheapexpr(l->n, init);
nsrc = n->list->n;
+
+ // Resolve slice type of multi-valued return.
+ if(istype(nsrc->type, TSTRUCT))
+ nsrc->type = nsrc->type->type->type;
argc = count(n->list) - 1;
if (argc < 1) {
return nsrc;
@@ -2705,7 +2737,7 @@ append(Node *n, NodeList **init)
return ns;
}
-// Lower copy(a, b) to a memmove call.
+// Lower copy(a, b) to a memmove call or a runtime call.
//
// init {
// n := len(a)
@@ -2717,11 +2749,22 @@ append(Node *n, NodeList **init)
// Also works if b is a string.
//
static Node*
-copyany(Node *n, NodeList **init)
+copyany(Node *n, NodeList **init, int runtimecall)
{
Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
NodeList *l;
+ if(runtimecall) {
+ if(n->right->type->etype == TSTRING)
+ fn = syslook("slicestringcopy", 1);
+ else
+ fn = syslook("copy", 1);
+ argtype(fn, n->left->type);
+ argtype(fn, n->right->type);
+ return mkcall1(fn, n->type, init,
+ n->left, n->right,
+ nodintconst(n->left->type->type->width));
+ }
walkexpr(&n->left, init);
walkexpr(&n->right, init);
nl = temp(n->left->type);
@@ -2802,17 +2845,13 @@ sliceany(Node* n, NodeList **init)
if(isconst(cb, CTINT)) {
cbv = mpgetfix(cb->val.u.xval);
- if(cbv < 0 || cbv > bv) {
+ if(cbv < 0 || cbv > bv)
yyerror("slice index out of bounds");
- cbv = -1;
- }
}
if(isconst(hb, CTINT)) {
hbv = mpgetfix(hb->val.u.xval);
- if(hbv < 0 || hbv > bv) {
+ if(hbv < 0 || hbv > bv)
yyerror("slice index out of bounds");
- hbv = -1;
- }
}
if(isconst(lb, CTINT)) {
lbv = mpgetfix(lb->val.u.xval);
@@ -3052,13 +3091,10 @@ walkcompare(Node **np, NodeList **init)
}
if(expr == N)
expr = nodbool(n->op == OEQ);
- typecheck(&expr, Erv);
- walkexpr(&expr, init);
- expr->type = n->type;
- *np = expr;
- return;
+ r = expr;
+ goto ret;
}
-
+
if(t->etype == TSTRUCT && countfield(t) <= 4) {
// Struct of four or fewer fields.
// Inline comparisons.
@@ -3075,13 +3111,10 @@ walkcompare(Node **np, NodeList **init)
}
if(expr == N)
expr = nodbool(n->op == OEQ);
- typecheck(&expr, Erv);
- walkexpr(&expr, init);
- expr->type = n->type;
- *np = expr;
- return;
+ r = expr;
+ goto ret;
}
-
+
// Chose not to inline, but still have addresses.
// Call equality function directly.
// The equality function requires a bool pointer for
@@ -3114,10 +3147,7 @@ walkcompare(Node **np, NodeList **init)
if(n->op != OEQ)
r = nod(ONOT, r, N);
- typecheck(&r, Erv);
- walkexpr(&r, init);
- *np = r;
- return;
+ goto ret;
hard:
// Cannot take address of one or both of the operands.
@@ -3133,7 +3163,16 @@ hard:
r = mkcall1(fn, n->type, init, typename(n->left->type), l, r);
if(n->op == ONE) {
r = nod(ONOT, r, N);
- typecheck(&r, Erv);
+ }
+ goto ret;
+
+ret:
+ typecheck(&r, Erv);
+ walkexpr(&r, init);
+ if(r->type != n->type) {
+ r = nod(OCONVNOP, r, N);
+ r->type = n->type;
+ r->typecheck = 1;
}
*np = r;
return;
diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c
index 390ad80b3..08d8ecff2 100644
--- a/src/cmd/gc/y.tab.c
+++ b/src/cmd/gc/y.tab.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison implementation for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
@@ -44,7 +47,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -52,52 +55,11 @@
/* Pure parsers. */
#define YYPURE 0
-/* Push parsers. */
-#define YYPUSH 0
-
-/* Pull parsers. */
-#define YYPULL 1
-
/* Using locations. */
#define YYLSP_NEEDED 0
-/* Copy the first part of user declarations. */
-
-/* Line 268 of yacc.c */
-#line 20 "go.y"
-
-#include <u.h>
-#include <stdio.h> /* if we don't, bison will, and go.h re-#defines getc */
-#include <libc.h>
-#include "go.h"
-
-static void fixlbrace(int);
-
-
-/* Line 268 of yacc.c */
-#line 81 "y.tab.c"
-
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 1
-#endif
-
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -209,36 +171,61 @@ static void fixlbrace(int);
+/* Copy the first part of user declarations. */
+#line 20 "go.y"
+
+#include <u.h>
+#include <stdio.h> /* if we don't, bison will, and go.h re-#defines getc */
+#include <libc.h>
+#include "go.h"
+
+static void fixlbrace(int);
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 293 of yacc.c */
#line 28 "go.y"
-
+{
Node* node;
NodeList* list;
Type* type;
Sym* sym;
struct Val val;
int i;
-
-
-
-/* Line 293 of yacc.c */
-#line 230 "y.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c. */
+#line 216 "y.tab.c"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
+
/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 242 "y.tab.c"
+/* Line 216 of yacc.c. */
+#line 229 "y.tab.c"
#ifdef short
# undef short
@@ -313,14 +300,14 @@ typedef short int yytype_int16;
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static int
-YYID (int yyi)
+YYID (int i)
#else
static int
-YYID (yyi)
- int yyi;
+YYID (i)
+ int i;
#endif
{
- return yyi;
+ return i;
}
#endif
@@ -341,11 +328,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# endif
@@ -368,24 +355,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+# if (defined __cplusplus && ! defined _STDLIB_H \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@@ -401,9 +388,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- yytype_int16 yyss_alloc;
- YYSTYPE yyvs_alloc;
-};
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
/* The size of the maximum gap between one aligned stack and the next. */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -414,27 +401,6 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-# define YYCOPY_NEEDED 1
-
-/* Relocate STACK from its old location to the new one. The
- local variables YYSIZE and YYSTACKSIZE give the old and new number of
- elements in the stack, and YYPTR gives the new location of the
- stack. Advance YYPTR to a properly aligned location for the next
- stack. */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
- do \
- { \
- YYSIZE_T yynewbytes; \
- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
- Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
- } \
- while (YYID (0))
-
-#endif
-
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
@@ -452,7 +418,24 @@ union yyalloc
while (YYID (0))
# endif
# endif
-#endif /* !YYCOPY_NEEDED */
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 4
@@ -681,36 +664,36 @@ static const yytype_uint16 yyrline[] =
308, 312, 316, 322, 328, 334, 339, 343, 347, 353,
359, 363, 367, 373, 377, 383, 384, 388, 394, 403,
409, 427, 432, 444, 460, 465, 472, 492, 510, 519,
- 538, 537, 552, 551, 582, 585, 592, 591, 602, 608,
- 617, 628, 634, 637, 645, 644, 655, 661, 673, 677,
- 682, 672, 703, 702, 715, 718, 724, 727, 739, 743,
- 738, 761, 760, 776, 777, 781, 785, 789, 793, 797,
- 801, 805, 809, 813, 817, 821, 825, 829, 833, 837,
- 841, 845, 849, 854, 860, 861, 865, 876, 880, 884,
- 888, 893, 897, 907, 911, 916, 924, 928, 929, 940,
- 944, 948, 952, 956, 964, 965, 971, 978, 984, 991,
- 994, 1001, 1007, 1024, 1031, 1032, 1039, 1040, 1059, 1060,
- 1063, 1066, 1070, 1081, 1090, 1096, 1099, 1102, 1109, 1110,
- 1116, 1129, 1144, 1152, 1164, 1169, 1175, 1176, 1177, 1178,
- 1179, 1180, 1186, 1187, 1188, 1189, 1195, 1196, 1197, 1198,
- 1199, 1205, 1206, 1209, 1212, 1213, 1214, 1215, 1216, 1219,
- 1220, 1233, 1237, 1242, 1247, 1252, 1256, 1257, 1260, 1266,
- 1273, 1279, 1286, 1292, 1303, 1317, 1346, 1386, 1411, 1429,
- 1438, 1441, 1449, 1453, 1457, 1464, 1470, 1475, 1487, 1490,
- 1500, 1501, 1507, 1508, 1514, 1518, 1524, 1525, 1531, 1535,
- 1541, 1564, 1569, 1575, 1581, 1588, 1597, 1606, 1621, 1627,
- 1632, 1636, 1643, 1656, 1657, 1663, 1669, 1672, 1676, 1682,
- 1685, 1694, 1697, 1698, 1702, 1703, 1709, 1710, 1711, 1712,
- 1713, 1715, 1714, 1729, 1734, 1738, 1742, 1746, 1750, 1755,
- 1774, 1780, 1788, 1792, 1798, 1802, 1808, 1812, 1818, 1822,
- 1831, 1835, 1839, 1843, 1849, 1852, 1860, 1861, 1863, 1864,
- 1867, 1870, 1873, 1876, 1879, 1882, 1885, 1888, 1891, 1894,
- 1897, 1900, 1903, 1906, 1912, 1916, 1920, 1924, 1928, 1932,
- 1952, 1959, 1970, 1971, 1972, 1975, 1976, 1979, 1983, 1993,
- 1997, 2001, 2005, 2009, 2013, 2017, 2023, 2029, 2037, 2045,
- 2051, 2058, 2074, 2096, 2100, 2106, 2109, 2112, 2116, 2126,
- 2130, 2145, 2153, 2154, 2166, 2167, 2170, 2174, 2180, 2184,
- 2190, 2194
+ 538, 537, 552, 551, 583, 586, 593, 592, 603, 609,
+ 618, 629, 635, 638, 646, 645, 656, 662, 674, 678,
+ 683, 673, 704, 703, 716, 719, 725, 728, 740, 744,
+ 739, 762, 761, 777, 778, 782, 786, 790, 794, 798,
+ 802, 806, 810, 814, 818, 822, 826, 830, 834, 838,
+ 842, 846, 850, 855, 861, 862, 866, 877, 881, 885,
+ 889, 894, 898, 908, 912, 917, 925, 929, 930, 941,
+ 945, 949, 953, 957, 965, 966, 972, 979, 985, 992,
+ 995, 1002, 1008, 1025, 1032, 1033, 1040, 1041, 1060, 1061,
+ 1064, 1067, 1071, 1082, 1091, 1097, 1100, 1103, 1110, 1111,
+ 1117, 1130, 1145, 1153, 1165, 1170, 1176, 1177, 1178, 1179,
+ 1180, 1181, 1187, 1188, 1189, 1190, 1196, 1197, 1198, 1199,
+ 1200, 1206, 1207, 1210, 1213, 1214, 1215, 1216, 1217, 1220,
+ 1221, 1234, 1238, 1243, 1248, 1253, 1257, 1258, 1261, 1267,
+ 1274, 1280, 1287, 1293, 1304, 1318, 1347, 1387, 1412, 1430,
+ 1439, 1442, 1450, 1454, 1458, 1465, 1471, 1476, 1488, 1491,
+ 1501, 1502, 1508, 1509, 1515, 1519, 1525, 1526, 1532, 1536,
+ 1542, 1565, 1570, 1576, 1582, 1589, 1598, 1607, 1622, 1628,
+ 1633, 1637, 1644, 1657, 1658, 1664, 1670, 1673, 1677, 1683,
+ 1686, 1695, 1698, 1699, 1703, 1704, 1710, 1711, 1712, 1713,
+ 1714, 1716, 1715, 1730, 1736, 1740, 1744, 1748, 1752, 1757,
+ 1776, 1782, 1790, 1794, 1800, 1804, 1810, 1814, 1820, 1824,
+ 1833, 1837, 1841, 1845, 1851, 1854, 1862, 1863, 1865, 1866,
+ 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896,
+ 1899, 1902, 1905, 1908, 1914, 1918, 1922, 1926, 1930, 1934,
+ 1954, 1961, 1972, 1973, 1974, 1977, 1978, 1981, 1985, 1995,
+ 1999, 2003, 2007, 2011, 2015, 2019, 2025, 2031, 2039, 2047,
+ 2053, 2060, 2076, 2098, 2102, 2108, 2111, 2114, 2118, 2128,
+ 2132, 2151, 2159, 2160, 2172, 2173, 2176, 2180, 2186, 2190,
+ 2196, 2200
};
#endif
@@ -729,16 +712,16 @@ const char *yytname[] =
"'/'", "'%'", "'&'", "NotPackage", "NotParen", "'('", "')'",
"PreferToRightParen", "';'", "'.'", "'$'", "'='", "':'", "'{'", "'}'",
"'!'", "'~'", "'['", "']'", "'?'", "'@'", "','", "$accept", "file",
- "package", "loadsys", "$@1", "imports", "import", "import_stmt",
+ "package", "loadsys", "@1", "imports", "import", "import_stmt",
"import_stmt_list", "import_here", "import_package", "import_safety",
- "import_there", "$@2", "xdcl", "common_dcl", "lconst", "vardcl",
+ "import_there", "@2", "xdcl", "common_dcl", "lconst", "vardcl",
"constdcl", "constdcl1", "typedclname", "typedcl", "simple_stmt", "case",
- "compound_stmt", "$@3", "caseblock", "$@4", "caseblock_list",
- "loop_body", "$@5", "range_stmt", "for_header", "for_body", "for_stmt",
- "$@6", "if_header", "if_stmt", "$@7", "$@8", "$@9", "elseif", "$@10",
- "elseif_list", "else", "switch_stmt", "$@11", "$@12", "select_stmt",
- "$@13", "expr", "uexpr", "pseudocall", "pexpr_no_paren", "start_complit",
- "keyval", "bare_complitexpr", "complitexpr", "pexpr", "expr_or_type",
+ "compound_stmt", "@3", "caseblock", "@4", "caseblock_list", "loop_body",
+ "@5", "range_stmt", "for_header", "for_body", "for_stmt", "@6",
+ "if_header", "if_stmt", "@7", "@8", "@9", "elseif", "@10", "elseif_list",
+ "else", "switch_stmt", "@11", "@12", "select_stmt", "@13", "expr",
+ "uexpr", "pseudocall", "pexpr_no_paren", "start_complit", "keyval",
+ "bare_complitexpr", "complitexpr", "pexpr", "expr_or_type",
"name_or_type", "lbrace", "new_name", "dcl_name", "onew_name", "sym",
"hidden_importsym", "name", "labelname", "dotdotdot", "ntype",
"non_expr_type", "non_recvchantype", "convtype", "comptype",
@@ -748,7 +731,7 @@ const char *yytname[] =
"vardcl_list", "constdcl_list", "typedcl_list", "structdcl_list",
"interfacedcl_list", "structdcl", "packname", "embed", "interfacedcl",
"indcl", "arg_type", "arg_type_list", "oarg_type_list_ocomma", "stmt",
- "non_dcl_stmt", "$@14", "stmt_list", "new_name_list", "dcl_name_list",
+ "non_dcl_stmt", "@14", "stmt_list", "new_name_list", "dcl_name_list",
"expr_list", "expr_or_type_list", "keyval_list", "braced_keyval_list",
"osemi", "ocomma", "oexpr", "oexpr_list", "osimple_stmt",
"ohidden_funarg_list", "ohidden_structdcl_list",
@@ -861,8 +844,8 @@ static const yytype_uint8 yyr2[] =
1, 3
};
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint16 yydefact[] =
{
@@ -1051,7 +1034,8 @@ static const yytype_int16 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If YYTABLE_NINF, syntax error. */
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -277
static const yytype_int16 yytable[] =
{
@@ -1285,12 +1269,6 @@ static const yytype_int16 yytable[] =
198
};
-#define yypact_value_is_default(yystate) \
- ((yystate) == (-474))
-
-#define yytable_value_is_error(yytable_value) \
- YYID (0)
-
static const yytype_int16 yycheck[] =
{
37, 37, 61, 143, 67, 37, 37, 202, 324, 251,
@@ -1608,18 +1586,9 @@ static const yytype_uint8 yystos[] =
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. However,
- YYFAIL appears to be in use. Nevertheless, it is formally deprecated
- in Bison 2.4.2's NEWS entry, where a plan to phase it out is
- discussed. */
+ Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
-#if defined YYFAIL
- /* This is here to suppress warnings from the GCC cpp's
- -Wunused-macros. Normally we don't worry about that warning, but
- some users do, and we want to make it easy for users to remove
- YYFAIL uses, which will produce warnings from Bison 2.5. */
-#endif
#define YYRECOVERING() (!!yyerrstatus)
@@ -1629,6 +1598,7 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@@ -1670,10 +1640,19 @@ while (YYID (0))
#endif
-/* This macro is provided for backward compatibility. */
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
#endif
@@ -1777,20 +1756,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
-yy_stack_print (yybottom, yytop)
- yytype_int16 *yybottom;
- yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (; yybottom <= yytop; yybottom++)
- {
- int yybot = *yybottom;
- YYFPRINTF (stderr, " %d", yybot);
- }
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -1824,11 +1800,11 @@ yy_reduce_print (yyvsp, yyrule)
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ fprintf (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
);
- YYFPRINTF (stderr, "\n");
+ fprintf (stderr, "\n");
}
}
@@ -1865,6 +1841,7 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
+
#if YYERROR_VERBOSE
@@ -1967,142 +1944,115 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return 2 if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- /* Internationalized format string. */
- const char *yyformat = 0;
- /* Arguments of yyformat. */
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
- int yycount = 0;
-
- /* There are many possibilities here to consider:
- - Assume YYFAIL is not used. It's too flawed to consider. See
- <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
- for details. YYERROR is fine as it does not invoke this
- function.
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yytoken != YYEMPTY)
- {
- int yyn = yypact[*yyssp];
- yyarg[yycount++] = yytname[yytoken];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
- }
- }
+ int yyn = yypact[yystate];
- switch (yycount)
- {
-# define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
- }
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
- yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return 1;
- }
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyformat += 2;
- }
- else
- {
- yyp++;
- yyformat++;
- }
- }
- return 0;
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
}
#endif /* YYERROR_VERBOSE */
+
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@@ -2134,9 +2084,10 @@ yydestruct (yymsg, yytype, yyvaluep)
break;
}
}
-
+
/* Prevent warnings from -Wmissing-prototypes. */
+
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
@@ -2152,16 +2103,18 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
-/* The lookahead symbol. */
+
+/* The look-ahead symbol. */
int yychar, yystate;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
int yynerrs;
+
/*----------.
| yyparse. |
`----------*/
@@ -2188,36 +2141,13 @@ yyparse ()
#endif
#endif
{
- /* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
-
- /* The stacks and their tools:
- `yyss': related to states.
- `yyvs': related to semantic values.
-
- Refer to the stacks thru separate pointers, to allow yyoverflow
- to reallocate them elsewhere. */
-
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
-
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
-
- YYSIZE_T yystacksize;
-
+
int yyn;
int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken;
- /* The variables used to return semantic value and location from the
- action routines. */
- YYSTYPE yyval;
-
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
@@ -2225,28 +2155,51 @@ yyparse ()
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yytoken = 0;
- yyss = yyssa;
- yyvs = yyvsa;
- yystacksize = YYINITDEPTH;
-
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
+ yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
+
yyssp = yyss;
yyvsp = yyvs;
@@ -2276,6 +2229,7 @@ yyparse ()
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
+
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
@@ -2283,6 +2237,7 @@ yyparse ()
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
+
&yystacksize);
yyss = yyss1;
@@ -2305,8 +2260,9 @@ yyparse ()
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
- YYSTACK_RELOCATE (yyss_alloc, yyss);
- YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@@ -2317,6 +2273,7 @@ yyparse ()
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
+
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
@@ -2326,9 +2283,6 @@ yyparse ()
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
- if (yystate == YYFINAL)
- YYACCEPT;
-
goto yybackup;
/*-----------.
@@ -2337,16 +2291,16 @@ yyparse ()
yybackup:
/* Do appropriate processing given the current state. Read a
- lookahead token if we need one and don't already have one. */
+ look-ahead token if we need one and don't already have one. */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
- if (yypact_value_is_default (yyn))
+ if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
@@ -2372,22 +2326,26 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yytable_value_is_error (yyn))
- goto yyerrlab;
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
- /* Shift the lookahead token. */
+ /* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the shifted token. */
- yychar = YYEMPTY;
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
@@ -2427,8 +2385,6 @@ yyreduce:
switch (yyn)
{
case 2:
-
-/* Line 1806 of yacc.c */
#line 128 "go.y"
{
xtop = concat(xtop, (yyvsp[(4) - (4)].list));
@@ -2436,8 +2392,6 @@ yyreduce:
break;
case 3:
-
-/* Line 1806 of yacc.c */
#line 134 "go.y"
{
prevlineno = lineno;
@@ -2447,8 +2401,6 @@ yyreduce:
break;
case 4:
-
-/* Line 1806 of yacc.c */
#line 140 "go.y"
{
mkpackage((yyvsp[(2) - (3)].sym)->name);
@@ -2456,8 +2408,6 @@ yyreduce:
break;
case 5:
-
-/* Line 1806 of yacc.c */
#line 150 "go.y"
{
importpkg = runtimepkg;
@@ -2471,8 +2421,6 @@ yyreduce:
break;
case 6:
-
-/* Line 1806 of yacc.c */
#line 161 "go.y"
{
importpkg = nil;
@@ -2480,8 +2428,6 @@ yyreduce:
break;
case 12:
-
-/* Line 1806 of yacc.c */
#line 175 "go.y"
{
Pkg *ipkg;
@@ -2522,8 +2468,6 @@ yyreduce:
break;
case 13:
-
-/* Line 1806 of yacc.c */
#line 212 "go.y"
{
// When an invalid import path is passed to importfile,
@@ -2536,8 +2480,6 @@ yyreduce:
break;
case 16:
-
-/* Line 1806 of yacc.c */
#line 227 "go.y"
{
// import with original name
@@ -2548,8 +2490,6 @@ yyreduce:
break;
case 17:
-
-/* Line 1806 of yacc.c */
#line 234 "go.y"
{
// import with given name
@@ -2560,8 +2500,6 @@ yyreduce:
break;
case 18:
-
-/* Line 1806 of yacc.c */
#line 241 "go.y"
{
// import into my name space
@@ -2572,8 +2510,6 @@ yyreduce:
break;
case 19:
-
-/* Line 1806 of yacc.c */
#line 250 "go.y"
{
if(importpkg->name == nil) {
@@ -2590,8 +2526,6 @@ yyreduce:
break;
case 21:
-
-/* Line 1806 of yacc.c */
#line 265 "go.y"
{
if(strcmp((yyvsp[(1) - (1)].sym)->name, "safe") == 0)
@@ -2600,8 +2534,6 @@ yyreduce:
break;
case 22:
-
-/* Line 1806 of yacc.c */
#line 271 "go.y"
{
defercheckwidth();
@@ -2609,8 +2541,6 @@ yyreduce:
break;
case 23:
-
-/* Line 1806 of yacc.c */
#line 275 "go.y"
{
resumecheckwidth();
@@ -2619,8 +2549,6 @@ yyreduce:
break;
case 24:
-
-/* Line 1806 of yacc.c */
#line 284 "go.y"
{
yyerror("empty top-level declaration");
@@ -2629,8 +2557,6 @@ yyreduce:
break;
case 26:
-
-/* Line 1806 of yacc.c */
#line 290 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
@@ -2638,8 +2564,6 @@ yyreduce:
break;
case 27:
-
-/* Line 1806 of yacc.c */
#line 294 "go.y"
{
yyerror("non-declaration statement outside function body");
@@ -2648,8 +2572,6 @@ yyreduce:
break;
case 28:
-
-/* Line 1806 of yacc.c */
#line 299 "go.y"
{
(yyval.list) = nil;
@@ -2657,8 +2579,6 @@ yyreduce:
break;
case 29:
-
-/* Line 1806 of yacc.c */
#line 305 "go.y"
{
(yyval.list) = (yyvsp[(2) - (2)].list);
@@ -2666,8 +2586,6 @@ yyreduce:
break;
case 30:
-
-/* Line 1806 of yacc.c */
#line 309 "go.y"
{
(yyval.list) = (yyvsp[(3) - (5)].list);
@@ -2675,8 +2593,6 @@ yyreduce:
break;
case 31:
-
-/* Line 1806 of yacc.c */
#line 313 "go.y"
{
(yyval.list) = nil;
@@ -2684,8 +2600,6 @@ yyreduce:
break;
case 32:
-
-/* Line 1806 of yacc.c */
#line 317 "go.y"
{
(yyval.list) = (yyvsp[(2) - (2)].list);
@@ -2695,8 +2609,6 @@ yyreduce:
break;
case 33:
-
-/* Line 1806 of yacc.c */
#line 323 "go.y"
{
(yyval.list) = (yyvsp[(3) - (5)].list);
@@ -2706,8 +2618,6 @@ yyreduce:
break;
case 34:
-
-/* Line 1806 of yacc.c */
#line 329 "go.y"
{
(yyval.list) = concat((yyvsp[(3) - (7)].list), (yyvsp[(5) - (7)].list));
@@ -2717,8 +2627,6 @@ yyreduce:
break;
case 35:
-
-/* Line 1806 of yacc.c */
#line 335 "go.y"
{
(yyval.list) = nil;
@@ -2727,8 +2635,6 @@ yyreduce:
break;
case 36:
-
-/* Line 1806 of yacc.c */
#line 340 "go.y"
{
(yyval.list) = list1((yyvsp[(2) - (2)].node));
@@ -2736,8 +2642,6 @@ yyreduce:
break;
case 37:
-
-/* Line 1806 of yacc.c */
#line 344 "go.y"
{
(yyval.list) = (yyvsp[(3) - (5)].list);
@@ -2745,8 +2649,6 @@ yyreduce:
break;
case 38:
-
-/* Line 1806 of yacc.c */
#line 348 "go.y"
{
(yyval.list) = nil;
@@ -2754,8 +2656,6 @@ yyreduce:
break;
case 39:
-
-/* Line 1806 of yacc.c */
#line 354 "go.y"
{
iota = 0;
@@ -2763,8 +2663,6 @@ yyreduce:
break;
case 40:
-
-/* Line 1806 of yacc.c */
#line 360 "go.y"
{
(yyval.list) = variter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
@@ -2772,8 +2670,6 @@ yyreduce:
break;
case 41:
-
-/* Line 1806 of yacc.c */
#line 364 "go.y"
{
(yyval.list) = variter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
@@ -2781,8 +2677,6 @@ yyreduce:
break;
case 42:
-
-/* Line 1806 of yacc.c */
#line 368 "go.y"
{
(yyval.list) = variter((yyvsp[(1) - (3)].list), nil, (yyvsp[(3) - (3)].list));
@@ -2790,8 +2684,6 @@ yyreduce:
break;
case 43:
-
-/* Line 1806 of yacc.c */
#line 374 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (4)].list), (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].list));
@@ -2799,8 +2691,6 @@ yyreduce:
break;
case 44:
-
-/* Line 1806 of yacc.c */
#line 378 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (3)].list), N, (yyvsp[(3) - (3)].list));
@@ -2808,8 +2698,6 @@ yyreduce:
break;
case 46:
-
-/* Line 1806 of yacc.c */
#line 385 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node), nil);
@@ -2817,8 +2705,6 @@ yyreduce:
break;
case 47:
-
-/* Line 1806 of yacc.c */
#line 389 "go.y"
{
(yyval.list) = constiter((yyvsp[(1) - (1)].list), N, nil);
@@ -2826,8 +2712,6 @@ yyreduce:
break;
case 48:
-
-/* Line 1806 of yacc.c */
#line 395 "go.y"
{
// different from dclname because the name
@@ -2838,8 +2722,6 @@ yyreduce:
break;
case 49:
-
-/* Line 1806 of yacc.c */
#line 404 "go.y"
{
(yyval.node) = typedcl1((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node), 1);
@@ -2847,8 +2729,6 @@ yyreduce:
break;
case 50:
-
-/* Line 1806 of yacc.c */
#line 410 "go.y"
{
(yyval.node) = (yyvsp[(1) - (1)].node);
@@ -2870,8 +2750,6 @@ yyreduce:
break;
case 51:
-
-/* Line 1806 of yacc.c */
#line 428 "go.y"
{
(yyval.node) = nod(OASOP, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2880,8 +2758,6 @@ yyreduce:
break;
case 52:
-
-/* Line 1806 of yacc.c */
#line 433 "go.y"
{
if((yyvsp[(1) - (3)].list)->next == nil && (yyvsp[(3) - (3)].list)->next == nil) {
@@ -2897,8 +2773,6 @@ yyreduce:
break;
case 53:
-
-/* Line 1806 of yacc.c */
#line 445 "go.y"
{
if((yyvsp[(3) - (3)].list)->n->op == OTYPESW) {
@@ -2918,8 +2792,6 @@ yyreduce:
break;
case 54:
-
-/* Line 1806 of yacc.c */
#line 461 "go.y"
{
(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
@@ -2928,8 +2800,6 @@ yyreduce:
break;
case 55:
-
-/* Line 1806 of yacc.c */
#line 466 "go.y"
{
(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
@@ -2938,8 +2808,6 @@ yyreduce:
break;
case 56:
-
-/* Line 1806 of yacc.c */
#line 473 "go.y"
{
Node *n, *nn;
@@ -2963,8 +2831,6 @@ yyreduce:
break;
case 57:
-
-/* Line 1806 of yacc.c */
#line 493 "go.y"
{
Node *n;
@@ -2986,8 +2852,6 @@ yyreduce:
break;
case 58:
-
-/* Line 1806 of yacc.c */
#line 511 "go.y"
{
// will be converted to OCASE
@@ -3000,8 +2864,6 @@ yyreduce:
break;
case 59:
-
-/* Line 1806 of yacc.c */
#line 520 "go.y"
{
Node *n, *nn;
@@ -3021,8 +2883,6 @@ yyreduce:
break;
case 60:
-
-/* Line 1806 of yacc.c */
#line 538 "go.y"
{
markdcl();
@@ -3030,8 +2890,6 @@ yyreduce:
break;
case 61:
-
-/* Line 1806 of yacc.c */
#line 542 "go.y"
{
if((yyvsp[(3) - (4)].list) == nil)
@@ -3043,8 +2901,6 @@ yyreduce:
break;
case 62:
-
-/* Line 1806 of yacc.c */
#line 552 "go.y"
{
// If the last token read by the lexer was consumed
@@ -3054,13 +2910,12 @@ yyreduce:
// This is so that the stmt_list action doesn't look at
// the case tokens if the stmt_list is empty.
yylast = yychar;
+ (yyvsp[(1) - (1)].node)->xoffset = block;
}
break;
case 63:
-
-/* Line 1806 of yacc.c */
-#line 562 "go.y"
+#line 563 "go.y"
{
int last;
@@ -3082,36 +2937,28 @@ yyreduce:
break;
case 64:
-
-/* Line 1806 of yacc.c */
-#line 582 "go.y"
+#line 583 "go.y"
{
(yyval.list) = nil;
}
break;
case 65:
-
-/* Line 1806 of yacc.c */
-#line 586 "go.y"
+#line 587 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
}
break;
case 66:
-
-/* Line 1806 of yacc.c */
-#line 592 "go.y"
+#line 593 "go.y"
{
markdcl();
}
break;
case 67:
-
-/* Line 1806 of yacc.c */
-#line 596 "go.y"
+#line 597 "go.y"
{
(yyval.list) = (yyvsp[(3) - (4)].list);
popdcl();
@@ -3119,9 +2966,7 @@ yyreduce:
break;
case 68:
-
-/* Line 1806 of yacc.c */
-#line 603 "go.y"
+#line 604 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -3130,9 +2975,7 @@ yyreduce:
break;
case 69:
-
-/* Line 1806 of yacc.c */
-#line 609 "go.y"
+#line 610 "go.y"
{
(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -3142,9 +2985,7 @@ yyreduce:
break;
case 70:
-
-/* Line 1806 of yacc.c */
-#line 618 "go.y"
+#line 619 "go.y"
{
// init ; test ; incr
if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
@@ -3158,9 +2999,7 @@ yyreduce:
break;
case 71:
-
-/* Line 1806 of yacc.c */
-#line 629 "go.y"
+#line 630 "go.y"
{
// normal test
(yyval.node) = nod(OFOR, N, N);
@@ -3169,9 +3008,7 @@ yyreduce:
break;
case 73:
-
-/* Line 1806 of yacc.c */
-#line 638 "go.y"
+#line 639 "go.y"
{
(yyval.node) = (yyvsp[(1) - (2)].node);
(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
@@ -3179,18 +3016,14 @@ yyreduce:
break;
case 74:
-
-/* Line 1806 of yacc.c */
-#line 645 "go.y"
+#line 646 "go.y"
{
markdcl();
}
break;
case 75:
-
-/* Line 1806 of yacc.c */
-#line 649 "go.y"
+#line 650 "go.y"
{
(yyval.node) = (yyvsp[(3) - (3)].node);
popdcl();
@@ -3198,9 +3031,7 @@ yyreduce:
break;
case 76:
-
-/* Line 1806 of yacc.c */
-#line 656 "go.y"
+#line 657 "go.y"
{
// test
(yyval.node) = nod(OIF, N, N);
@@ -3209,9 +3040,7 @@ yyreduce:
break;
case 77:
-
-/* Line 1806 of yacc.c */
-#line 662 "go.y"
+#line 663 "go.y"
{
// init ; test
(yyval.node) = nod(OIF, N, N);
@@ -3222,18 +3051,14 @@ yyreduce:
break;
case 78:
-
-/* Line 1806 of yacc.c */
-#line 673 "go.y"
+#line 674 "go.y"
{
markdcl();
}
break;
case 79:
-
-/* Line 1806 of yacc.c */
-#line 677 "go.y"
+#line 678 "go.y"
{
if((yyvsp[(3) - (3)].node)->ntest == N)
yyerror("missing condition in if statement");
@@ -3241,18 +3066,14 @@ yyreduce:
break;
case 80:
-
-/* Line 1806 of yacc.c */
-#line 682 "go.y"
+#line 683 "go.y"
{
(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
}
break;
case 81:
-
-/* Line 1806 of yacc.c */
-#line 686 "go.y"
+#line 687 "go.y"
{
Node *n;
NodeList *nn;
@@ -3270,18 +3091,14 @@ yyreduce:
break;
case 82:
-
-/* Line 1806 of yacc.c */
-#line 703 "go.y"
+#line 704 "go.y"
{
markdcl();
}
break;
case 83:
-
-/* Line 1806 of yacc.c */
-#line 707 "go.y"
+#line 708 "go.y"
{
if((yyvsp[(4) - (5)].node)->ntest == N)
yyerror("missing condition in if statement");
@@ -3291,36 +3108,28 @@ yyreduce:
break;
case 84:
-
-/* Line 1806 of yacc.c */
-#line 715 "go.y"
+#line 716 "go.y"
{
(yyval.list) = nil;
}
break;
case 85:
-
-/* Line 1806 of yacc.c */
-#line 719 "go.y"
+#line 720 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list));
}
break;
case 86:
-
-/* Line 1806 of yacc.c */
-#line 724 "go.y"
+#line 725 "go.y"
{
(yyval.list) = nil;
}
break;
case 87:
-
-/* Line 1806 of yacc.c */
-#line 728 "go.y"
+#line 729 "go.y"
{
NodeList *node;
@@ -3332,18 +3141,14 @@ yyreduce:
break;
case 88:
-
-/* Line 1806 of yacc.c */
-#line 739 "go.y"
+#line 740 "go.y"
{
markdcl();
}
break;
case 89:
-
-/* Line 1806 of yacc.c */
-#line 743 "go.y"
+#line 744 "go.y"
{
Node *n;
n = (yyvsp[(3) - (3)].node)->ntest;
@@ -3354,9 +3159,7 @@ yyreduce:
break;
case 90:
-
-/* Line 1806 of yacc.c */
-#line 751 "go.y"
+#line 752 "go.y"
{
(yyval.node) = (yyvsp[(3) - (7)].node);
(yyval.node)->op = OSWITCH;
@@ -3367,18 +3170,14 @@ yyreduce:
break;
case 91:
-
-/* Line 1806 of yacc.c */
-#line 761 "go.y"
+#line 762 "go.y"
{
typesw = nod(OXXX, typesw, N);
}
break;
case 92:
-
-/* Line 1806 of yacc.c */
-#line 765 "go.y"
+#line 766 "go.y"
{
(yyval.node) = nod(OSELECT, N, N);
(yyval.node)->lineno = typesw->lineno;
@@ -3388,198 +3187,154 @@ yyreduce:
break;
case 94:
-
-/* Line 1806 of yacc.c */
-#line 778 "go.y"
+#line 779 "go.y"
{
(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 95:
-
-/* Line 1806 of yacc.c */
-#line 782 "go.y"
+#line 783 "go.y"
{
(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 96:
-
-/* Line 1806 of yacc.c */
-#line 786 "go.y"
+#line 787 "go.y"
{
(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 97:
-
-/* Line 1806 of yacc.c */
-#line 790 "go.y"
+#line 791 "go.y"
{
(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 98:
-
-/* Line 1806 of yacc.c */
-#line 794 "go.y"
+#line 795 "go.y"
{
(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 99:
-
-/* Line 1806 of yacc.c */
-#line 798 "go.y"
+#line 799 "go.y"
{
(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 100:
-
-/* Line 1806 of yacc.c */
-#line 802 "go.y"
+#line 803 "go.y"
{
(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 101:
-
-/* Line 1806 of yacc.c */
-#line 806 "go.y"
+#line 807 "go.y"
{
(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 102:
-
-/* Line 1806 of yacc.c */
-#line 810 "go.y"
+#line 811 "go.y"
{
(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 103:
-
-/* Line 1806 of yacc.c */
-#line 814 "go.y"
+#line 815 "go.y"
{
(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 104:
-
-/* Line 1806 of yacc.c */
-#line 818 "go.y"
+#line 819 "go.y"
{
(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 105:
-
-/* Line 1806 of yacc.c */
-#line 822 "go.y"
+#line 823 "go.y"
{
(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 106:
-
-/* Line 1806 of yacc.c */
-#line 826 "go.y"
+#line 827 "go.y"
{
(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 107:
-
-/* Line 1806 of yacc.c */
-#line 830 "go.y"
+#line 831 "go.y"
{
(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 108:
-
-/* Line 1806 of yacc.c */
-#line 834 "go.y"
+#line 835 "go.y"
{
(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 109:
-
-/* Line 1806 of yacc.c */
-#line 838 "go.y"
+#line 839 "go.y"
{
(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 110:
-
-/* Line 1806 of yacc.c */
-#line 842 "go.y"
+#line 843 "go.y"
{
(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 111:
-
-/* Line 1806 of yacc.c */
-#line 846 "go.y"
+#line 847 "go.y"
{
(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 112:
-
-/* Line 1806 of yacc.c */
-#line 850 "go.y"
+#line 851 "go.y"
{
(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 113:
-
-/* Line 1806 of yacc.c */
-#line 855 "go.y"
+#line 856 "go.y"
{
(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 115:
-
-/* Line 1806 of yacc.c */
-#line 862 "go.y"
+#line 863 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 116:
-
-/* Line 1806 of yacc.c */
-#line 866 "go.y"
+#line 867 "go.y"
{
if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
// Special case for &T{...}: turn into (*T){...}.
@@ -3593,36 +3348,28 @@ yyreduce:
break;
case 117:
-
-/* Line 1806 of yacc.c */
-#line 877 "go.y"
+#line 878 "go.y"
{
(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
}
break;
case 118:
-
-/* Line 1806 of yacc.c */
-#line 881 "go.y"
+#line 882 "go.y"
{
(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
}
break;
case 119:
-
-/* Line 1806 of yacc.c */
-#line 885 "go.y"
+#line 886 "go.y"
{
(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
}
break;
case 120:
-
-/* Line 1806 of yacc.c */
-#line 889 "go.y"
+#line 890 "go.y"
{
yyerror("the bitwise complement operator is ^");
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
@@ -3630,36 +3377,28 @@ yyreduce:
break;
case 121:
-
-/* Line 1806 of yacc.c */
-#line 894 "go.y"
+#line 895 "go.y"
{
(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
}
break;
case 122:
-
-/* Line 1806 of yacc.c */
-#line 898 "go.y"
+#line 899 "go.y"
{
(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
}
break;
case 123:
-
-/* Line 1806 of yacc.c */
-#line 908 "go.y"
+#line 909 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
}
break;
case 124:
-
-/* Line 1806 of yacc.c */
-#line 912 "go.y"
+#line 913 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3667,9 +3406,7 @@ yyreduce:
break;
case 125:
-
-/* Line 1806 of yacc.c */
-#line 917 "go.y"
+#line 918 "go.y"
{
(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
(yyval.node)->list = (yyvsp[(3) - (6)].list);
@@ -3678,18 +3415,14 @@ yyreduce:
break;
case 126:
-
-/* Line 1806 of yacc.c */
-#line 925 "go.y"
+#line 926 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
case 128:
-
-/* Line 1806 of yacc.c */
-#line 930 "go.y"
+#line 931 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
@@ -3703,45 +3436,35 @@ yyreduce:
break;
case 129:
-
-/* Line 1806 of yacc.c */
-#line 941 "go.y"
+#line 942 "go.y"
{
(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
}
break;
case 130:
-
-/* Line 1806 of yacc.c */
-#line 945 "go.y"
+#line 946 "go.y"
{
(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
}
break;
case 131:
-
-/* Line 1806 of yacc.c */
-#line 949 "go.y"
+#line 950 "go.y"
{
(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
}
break;
case 132:
-
-/* Line 1806 of yacc.c */
-#line 953 "go.y"
+#line 954 "go.y"
{
(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
}
break;
case 133:
-
-/* Line 1806 of yacc.c */
-#line 957 "go.y"
+#line 958 "go.y"
{
if((yyvsp[(5) - (8)].node) == N)
yyerror("middle index required in 3-index slice");
@@ -3752,9 +3475,7 @@ yyreduce:
break;
case 135:
-
-/* Line 1806 of yacc.c */
-#line 966 "go.y"
+#line 967 "go.y"
{
// conversion
(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
@@ -3763,9 +3484,7 @@ yyreduce:
break;
case 136:
-
-/* Line 1806 of yacc.c */
-#line 972 "go.y"
+#line 973 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3775,9 +3494,7 @@ yyreduce:
break;
case 137:
-
-/* Line 1806 of yacc.c */
-#line 979 "go.y"
+#line 980 "go.y"
{
(yyval.node) = (yyvsp[(3) - (5)].node);
(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3786,9 +3503,7 @@ yyreduce:
break;
case 138:
-
-/* Line 1806 of yacc.c */
-#line 985 "go.y"
+#line 986 "go.y"
{
yyerror("cannot parenthesize type in composite literal");
(yyval.node) = (yyvsp[(5) - (7)].node);
@@ -3798,9 +3513,7 @@ yyreduce:
break;
case 140:
-
-/* Line 1806 of yacc.c */
-#line 994 "go.y"
+#line 995 "go.y"
{
// composite expression.
// make node early so we get the right line number.
@@ -3809,18 +3522,14 @@ yyreduce:
break;
case 141:
-
-/* Line 1806 of yacc.c */
-#line 1002 "go.y"
+#line 1003 "go.y"
{
(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
}
break;
case 142:
-
-/* Line 1806 of yacc.c */
-#line 1008 "go.y"
+#line 1009 "go.y"
{
// These nodes do not carry line numbers.
// Since a composite literal commonly spans several lines,
@@ -3840,9 +3549,7 @@ yyreduce:
break;
case 143:
-
-/* Line 1806 of yacc.c */
-#line 1025 "go.y"
+#line 1026 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
@@ -3850,9 +3557,7 @@ yyreduce:
break;
case 145:
-
-/* Line 1806 of yacc.c */
-#line 1033 "go.y"
+#line 1034 "go.y"
{
(yyval.node) = (yyvsp[(2) - (4)].node);
(yyval.node)->list = (yyvsp[(3) - (4)].list);
@@ -3860,9 +3565,7 @@ yyreduce:
break;
case 147:
-
-/* Line 1806 of yacc.c */
-#line 1041 "go.y"
+#line 1042 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -3882,27 +3585,21 @@ yyreduce:
break;
case 151:
-
-/* Line 1806 of yacc.c */
-#line 1067 "go.y"
+#line 1068 "go.y"
{
(yyval.i) = LBODY;
}
break;
case 152:
-
-/* Line 1806 of yacc.c */
-#line 1071 "go.y"
+#line 1072 "go.y"
{
(yyval.i) = '{';
}
break;
case 153:
-
-/* Line 1806 of yacc.c */
-#line 1082 "go.y"
+#line 1083 "go.y"
{
if((yyvsp[(1) - (1)].sym) == S)
(yyval.node) = N;
@@ -3912,27 +3609,21 @@ yyreduce:
break;
case 154:
-
-/* Line 1806 of yacc.c */
-#line 1091 "go.y"
+#line 1092 "go.y"
{
(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
}
break;
case 155:
-
-/* Line 1806 of yacc.c */
-#line 1096 "go.y"
+#line 1097 "go.y"
{
(yyval.node) = N;
}
break;
case 157:
-
-/* Line 1806 of yacc.c */
-#line 1103 "go.y"
+#line 1104 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
// during imports, unqualified non-exported identifiers are from builtinpkg
@@ -3942,18 +3633,14 @@ yyreduce:
break;
case 159:
-
-/* Line 1806 of yacc.c */
-#line 1111 "go.y"
+#line 1112 "go.y"
{
(yyval.sym) = S;
}
break;
case 160:
-
-/* Line 1806 of yacc.c */
-#line 1117 "go.y"
+#line 1118 "go.y"
{
Pkg *p;
@@ -3969,9 +3656,7 @@ yyreduce:
break;
case 161:
-
-/* Line 1806 of yacc.c */
-#line 1130 "go.y"
+#line 1131 "go.y"
{
Pkg *p;
@@ -3987,9 +3672,7 @@ yyreduce:
break;
case 162:
-
-/* Line 1806 of yacc.c */
-#line 1145 "go.y"
+#line 1146 "go.y"
{
(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
if((yyval.node)->pack != N)
@@ -3998,9 +3681,7 @@ yyreduce:
break;
case 164:
-
-/* Line 1806 of yacc.c */
-#line 1165 "go.y"
+#line 1166 "go.y"
{
yyerror("final argument in variadic function missing type");
(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
@@ -4008,45 +3689,35 @@ yyreduce:
break;
case 165:
-
-/* Line 1806 of yacc.c */
-#line 1170 "go.y"
+#line 1171 "go.y"
{
(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
}
break;
case 171:
-
-/* Line 1806 of yacc.c */
-#line 1181 "go.y"
+#line 1182 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
case 175:
-
-/* Line 1806 of yacc.c */
-#line 1190 "go.y"
+#line 1191 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 180:
-
-/* Line 1806 of yacc.c */
-#line 1200 "go.y"
+#line 1201 "go.y"
{
(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
}
break;
case 190:
-
-/* Line 1806 of yacc.c */
-#line 1221 "go.y"
+#line 1222 "go.y"
{
if((yyvsp[(1) - (3)].node)->op == OPACK) {
Sym *s;
@@ -4060,18 +3731,14 @@ yyreduce:
break;
case 191:
-
-/* Line 1806 of yacc.c */
-#line 1234 "go.y"
+#line 1235 "go.y"
{
(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
}
break;
case 192:
-
-/* Line 1806 of yacc.c */
-#line 1238 "go.y"
+#line 1239 "go.y"
{
// array literal of nelem
(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
@@ -4079,9 +3746,7 @@ yyreduce:
break;
case 193:
-
-/* Line 1806 of yacc.c */
-#line 1243 "go.y"
+#line 1244 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
(yyval.node)->etype = Cboth;
@@ -4089,9 +3754,7 @@ yyreduce:
break;
case 194:
-
-/* Line 1806 of yacc.c */
-#line 1248 "go.y"
+#line 1249 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Csend;
@@ -4099,27 +3762,21 @@ yyreduce:
break;
case 195:
-
-/* Line 1806 of yacc.c */
-#line 1253 "go.y"
+#line 1254 "go.y"
{
(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
}
break;
case 198:
-
-/* Line 1806 of yacc.c */
-#line 1261 "go.y"
+#line 1262 "go.y"
{
(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
}
break;
case 199:
-
-/* Line 1806 of yacc.c */
-#line 1267 "go.y"
+#line 1268 "go.y"
{
(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
(yyval.node)->etype = Crecv;
@@ -4127,9 +3784,7 @@ yyreduce:
break;
case 200:
-
-/* Line 1806 of yacc.c */
-#line 1274 "go.y"
+#line 1275 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -4138,9 +3793,7 @@ yyreduce:
break;
case 201:
-
-/* Line 1806 of yacc.c */
-#line 1280 "go.y"
+#line 1281 "go.y"
{
(yyval.node) = nod(OTSTRUCT, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
@@ -4148,9 +3801,7 @@ yyreduce:
break;
case 202:
-
-/* Line 1806 of yacc.c */
-#line 1287 "go.y"
+#line 1288 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -4159,9 +3810,7 @@ yyreduce:
break;
case 203:
-
-/* Line 1806 of yacc.c */
-#line 1293 "go.y"
+#line 1294 "go.y"
{
(yyval.node) = nod(OTINTER, N, N);
fixlbrace((yyvsp[(2) - (3)].i));
@@ -4169,9 +3818,7 @@ yyreduce:
break;
case 204:
-
-/* Line 1806 of yacc.c */
-#line 1304 "go.y"
+#line 1305 "go.y"
{
(yyval.node) = (yyvsp[(2) - (3)].node);
if((yyval.node) == N)
@@ -4186,9 +3833,7 @@ yyreduce:
break;
case 205:
-
-/* Line 1806 of yacc.c */
-#line 1318 "go.y"
+#line 1319 "go.y"
{
Node *t;
@@ -4220,9 +3865,7 @@ yyreduce:
break;
case 206:
-
-/* Line 1806 of yacc.c */
-#line 1347 "go.y"
+#line 1348 "go.y"
{
Node *rcvr, *t;
@@ -4263,9 +3906,7 @@ yyreduce:
break;
case 207:
-
-/* Line 1806 of yacc.c */
-#line 1387 "go.y"
+#line 1388 "go.y"
{
Sym *s;
Type *t;
@@ -4293,9 +3934,7 @@ yyreduce:
break;
case 208:
-
-/* Line 1806 of yacc.c */
-#line 1412 "go.y"
+#line 1413 "go.y"
{
(yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right);
(yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list));
@@ -4314,9 +3953,7 @@ yyreduce:
break;
case 209:
-
-/* Line 1806 of yacc.c */
-#line 1430 "go.y"
+#line 1431 "go.y"
{
(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
(yyval.node) = nod(OTFUNC, N, N);
@@ -4326,18 +3963,14 @@ yyreduce:
break;
case 210:
-
-/* Line 1806 of yacc.c */
-#line 1438 "go.y"
+#line 1439 "go.y"
{
(yyval.list) = nil;
}
break;
case 211:
-
-/* Line 1806 of yacc.c */
-#line 1442 "go.y"
+#line 1443 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
if((yyval.list) == nil)
@@ -4346,27 +3979,21 @@ yyreduce:
break;
case 212:
-
-/* Line 1806 of yacc.c */
-#line 1450 "go.y"
+#line 1451 "go.y"
{
(yyval.list) = nil;
}
break;
case 213:
-
-/* Line 1806 of yacc.c */
-#line 1454 "go.y"
+#line 1455 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
}
break;
case 214:
-
-/* Line 1806 of yacc.c */
-#line 1458 "go.y"
+#line 1459 "go.y"
{
(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
(yyval.list) = (yyvsp[(2) - (3)].list);
@@ -4374,18 +4001,14 @@ yyreduce:
break;
case 215:
-
-/* Line 1806 of yacc.c */
-#line 1465 "go.y"
+#line 1466 "go.y"
{
closurehdr((yyvsp[(1) - (1)].node));
}
break;
case 216:
-
-/* Line 1806 of yacc.c */
-#line 1471 "go.y"
+#line 1472 "go.y"
{
(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
fixlbrace((yyvsp[(2) - (4)].i));
@@ -4393,27 +4016,21 @@ yyreduce:
break;
case 217:
-
-/* Line 1806 of yacc.c */
-#line 1476 "go.y"
+#line 1477 "go.y"
{
(yyval.node) = closurebody(nil);
}
break;
case 218:
-
-/* Line 1806 of yacc.c */
-#line 1487 "go.y"
+#line 1488 "go.y"
{
(yyval.list) = nil;
}
break;
case 219:
-
-/* Line 1806 of yacc.c */
-#line 1491 "go.y"
+#line 1492 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
if(nsyntaxerrors == 0)
@@ -4424,72 +4041,56 @@ yyreduce:
break;
case 221:
-
-/* Line 1806 of yacc.c */
-#line 1502 "go.y"
+#line 1503 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 223:
-
-/* Line 1806 of yacc.c */
-#line 1509 "go.y"
+#line 1510 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 224:
-
-/* Line 1806 of yacc.c */
-#line 1515 "go.y"
+#line 1516 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 225:
-
-/* Line 1806 of yacc.c */
-#line 1519 "go.y"
+#line 1520 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 227:
-
-/* Line 1806 of yacc.c */
-#line 1526 "go.y"
+#line 1527 "go.y"
{
(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
}
break;
case 228:
-
-/* Line 1806 of yacc.c */
-#line 1532 "go.y"
+#line 1533 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 229:
-
-/* Line 1806 of yacc.c */
-#line 1536 "go.y"
+#line 1537 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 230:
-
-/* Line 1806 of yacc.c */
-#line 1542 "go.y"
+#line 1543 "go.y"
{
NodeList *l;
@@ -4515,9 +4116,7 @@ yyreduce:
break;
case 231:
-
-/* Line 1806 of yacc.c */
-#line 1565 "go.y"
+#line 1566 "go.y"
{
(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
(yyval.list) = list1((yyvsp[(1) - (2)].node));
@@ -4525,9 +4124,7 @@ yyreduce:
break;
case 232:
-
-/* Line 1806 of yacc.c */
-#line 1570 "go.y"
+#line 1571 "go.y"
{
(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
(yyval.list) = list1((yyvsp[(2) - (4)].node));
@@ -4536,9 +4133,7 @@ yyreduce:
break;
case 233:
-
-/* Line 1806 of yacc.c */
-#line 1576 "go.y"
+#line 1577 "go.y"
{
(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
@@ -4547,9 +4142,7 @@ yyreduce:
break;
case 234:
-
-/* Line 1806 of yacc.c */
-#line 1582 "go.y"
+#line 1583 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4559,9 +4152,7 @@ yyreduce:
break;
case 235:
-
-/* Line 1806 of yacc.c */
-#line 1589 "go.y"
+#line 1590 "go.y"
{
(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4571,9 +4162,7 @@ yyreduce:
break;
case 236:
-
-/* Line 1806 of yacc.c */
-#line 1598 "go.y"
+#line 1599 "go.y"
{
Node *n;
@@ -4585,9 +4174,7 @@ yyreduce:
break;
case 237:
-
-/* Line 1806 of yacc.c */
-#line 1607 "go.y"
+#line 1608 "go.y"
{
Pkg *pkg;
@@ -4603,18 +4190,14 @@ yyreduce:
break;
case 238:
-
-/* Line 1806 of yacc.c */
-#line 1622 "go.y"
+#line 1623 "go.y"
{
(yyval.node) = embedded((yyvsp[(1) - (1)].sym), localpkg);
}
break;
case 239:
-
-/* Line 1806 of yacc.c */
-#line 1628 "go.y"
+#line 1629 "go.y"
{
(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
ifacedcl((yyval.node));
@@ -4622,18 +4205,14 @@ yyreduce:
break;
case 240:
-
-/* Line 1806 of yacc.c */
-#line 1633 "go.y"
+#line 1634 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
}
break;
case 241:
-
-/* Line 1806 of yacc.c */
-#line 1637 "go.y"
+#line 1638 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
yyerror("cannot parenthesize embedded type");
@@ -4641,9 +4220,7 @@ yyreduce:
break;
case 242:
-
-/* Line 1806 of yacc.c */
-#line 1644 "go.y"
+#line 1645 "go.y"
{
// without func keyword
(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
@@ -4654,9 +4231,7 @@ yyreduce:
break;
case 244:
-
-/* Line 1806 of yacc.c */
-#line 1658 "go.y"
+#line 1659 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4665,9 +4240,7 @@ yyreduce:
break;
case 245:
-
-/* Line 1806 of yacc.c */
-#line 1664 "go.y"
+#line 1665 "go.y"
{
(yyval.node) = nod(ONONAME, N, N);
(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4676,72 +4249,56 @@ yyreduce:
break;
case 247:
-
-/* Line 1806 of yacc.c */
-#line 1673 "go.y"
+#line 1674 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 248:
-
-/* Line 1806 of yacc.c */
-#line 1677 "go.y"
+#line 1678 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 249:
-
-/* Line 1806 of yacc.c */
-#line 1682 "go.y"
+#line 1683 "go.y"
{
(yyval.list) = nil;
}
break;
case 250:
-
-/* Line 1806 of yacc.c */
-#line 1686 "go.y"
+#line 1687 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
case 251:
-
-/* Line 1806 of yacc.c */
-#line 1694 "go.y"
+#line 1695 "go.y"
{
(yyval.node) = N;
}
break;
case 253:
-
-/* Line 1806 of yacc.c */
-#line 1699 "go.y"
+#line 1700 "go.y"
{
(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
}
break;
case 255:
-
-/* Line 1806 of yacc.c */
-#line 1704 "go.y"
+#line 1705 "go.y"
{
(yyval.node) = N;
}
break;
case 261:
-
-/* Line 1806 of yacc.c */
-#line 1715 "go.y"
+#line 1716 "go.y"
{
(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
(yyvsp[(1) - (2)].node)->sym = dclstack; // context, for goto restrictions
@@ -4749,9 +4306,7 @@ yyreduce:
break;
case 262:
-
-/* Line 1806 of yacc.c */
-#line 1720 "go.y"
+#line 1721 "go.y"
{
NodeList *l;
@@ -4764,55 +4319,44 @@ yyreduce:
break;
case 263:
-
-/* Line 1806 of yacc.c */
-#line 1730 "go.y"
+#line 1731 "go.y"
{
// will be converted to OFALL
(yyval.node) = nod(OXFALL, N, N);
+ (yyval.node)->xoffset = block;
}
break;
case 264:
-
-/* Line 1806 of yacc.c */
-#line 1735 "go.y"
+#line 1737 "go.y"
{
(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
}
break;
case 265:
-
-/* Line 1806 of yacc.c */
-#line 1739 "go.y"
+#line 1741 "go.y"
{
(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
}
break;
case 266:
-
-/* Line 1806 of yacc.c */
-#line 1743 "go.y"
+#line 1745 "go.y"
{
(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
}
break;
case 267:
-
-/* Line 1806 of yacc.c */
-#line 1747 "go.y"
+#line 1749 "go.y"
{
(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
}
break;
case 268:
-
-/* Line 1806 of yacc.c */
-#line 1751 "go.y"
+#line 1753 "go.y"
{
(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
(yyval.node)->sym = dclstack; // context, for goto restrictions
@@ -4820,9 +4364,7 @@ yyreduce:
break;
case 269:
-
-/* Line 1806 of yacc.c */
-#line 1756 "go.y"
+#line 1758 "go.y"
{
(yyval.node) = nod(ORETURN, N, N);
(yyval.node)->list = (yyvsp[(2) - (2)].list);
@@ -4842,9 +4384,7 @@ yyreduce:
break;
case 270:
-
-/* Line 1806 of yacc.c */
-#line 1775 "go.y"
+#line 1777 "go.y"
{
(yyval.list) = nil;
if((yyvsp[(1) - (1)].node) != N)
@@ -4853,9 +4393,7 @@ yyreduce:
break;
case 271:
-
-/* Line 1806 of yacc.c */
-#line 1781 "go.y"
+#line 1783 "go.y"
{
(yyval.list) = (yyvsp[(1) - (3)].list);
if((yyvsp[(3) - (3)].node) != N)
@@ -4864,243 +4402,189 @@ yyreduce:
break;
case 272:
-
-/* Line 1806 of yacc.c */
-#line 1789 "go.y"
+#line 1791 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 273:
-
-/* Line 1806 of yacc.c */
-#line 1793 "go.y"
+#line 1795 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 274:
-
-/* Line 1806 of yacc.c */
-#line 1799 "go.y"
+#line 1801 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 275:
-
-/* Line 1806 of yacc.c */
-#line 1803 "go.y"
+#line 1805 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 276:
-
-/* Line 1806 of yacc.c */
-#line 1809 "go.y"
+#line 1811 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 277:
-
-/* Line 1806 of yacc.c */
-#line 1813 "go.y"
+#line 1815 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 278:
-
-/* Line 1806 of yacc.c */
-#line 1819 "go.y"
+#line 1821 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 279:
-
-/* Line 1806 of yacc.c */
-#line 1823 "go.y"
+#line 1825 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 280:
-
-/* Line 1806 of yacc.c */
-#line 1832 "go.y"
+#line 1834 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 281:
-
-/* Line 1806 of yacc.c */
-#line 1836 "go.y"
+#line 1838 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 282:
-
-/* Line 1806 of yacc.c */
-#line 1840 "go.y"
+#line 1842 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 283:
-
-/* Line 1806 of yacc.c */
-#line 1844 "go.y"
+#line 1846 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 284:
-
-/* Line 1806 of yacc.c */
-#line 1849 "go.y"
+#line 1851 "go.y"
{
(yyval.list) = nil;
}
break;
case 285:
-
-/* Line 1806 of yacc.c */
-#line 1853 "go.y"
+#line 1855 "go.y"
{
(yyval.list) = (yyvsp[(1) - (2)].list);
}
break;
case 290:
-
-/* Line 1806 of yacc.c */
-#line 1867 "go.y"
+#line 1869 "go.y"
{
(yyval.node) = N;
}
break;
case 292:
-
-/* Line 1806 of yacc.c */
-#line 1873 "go.y"
+#line 1875 "go.y"
{
(yyval.list) = nil;
}
break;
case 294:
-
-/* Line 1806 of yacc.c */
-#line 1879 "go.y"
+#line 1881 "go.y"
{
(yyval.node) = N;
}
break;
case 296:
-
-/* Line 1806 of yacc.c */
-#line 1885 "go.y"
+#line 1887 "go.y"
{
(yyval.list) = nil;
}
break;
case 298:
-
-/* Line 1806 of yacc.c */
-#line 1891 "go.y"
+#line 1893 "go.y"
{
(yyval.list) = nil;
}
break;
case 300:
-
-/* Line 1806 of yacc.c */
-#line 1897 "go.y"
+#line 1899 "go.y"
{
(yyval.list) = nil;
}
break;
case 302:
-
-/* Line 1806 of yacc.c */
-#line 1903 "go.y"
+#line 1905 "go.y"
{
(yyval.val).ctype = CTxxx;
}
break;
case 304:
-
-/* Line 1806 of yacc.c */
-#line 1913 "go.y"
+#line 1915 "go.y"
{
importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
}
break;
case 305:
-
-/* Line 1806 of yacc.c */
-#line 1917 "go.y"
+#line 1919 "go.y"
{
importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
}
break;
case 306:
-
-/* Line 1806 of yacc.c */
-#line 1921 "go.y"
+#line 1923 "go.y"
{
importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
}
break;
case 307:
-
-/* Line 1806 of yacc.c */
-#line 1925 "go.y"
+#line 1927 "go.y"
{
importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
}
break;
case 308:
-
-/* Line 1806 of yacc.c */
-#line 1929 "go.y"
+#line 1931 "go.y"
{
importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
}
break;
case 309:
-
-/* Line 1806 of yacc.c */
-#line 1933 "go.y"
+#line 1935 "go.y"
{
if((yyvsp[(2) - (4)].node) == N) {
dclcontext = PEXTERN; // since we skip the funcbody below
@@ -5121,9 +4605,7 @@ yyreduce:
break;
case 310:
-
-/* Line 1806 of yacc.c */
-#line 1953 "go.y"
+#line 1955 "go.y"
{
(yyval.sym) = (yyvsp[(1) - (1)].sym);
structpkg = (yyval.sym)->pkg;
@@ -5131,9 +4613,7 @@ yyreduce:
break;
case 311:
-
-/* Line 1806 of yacc.c */
-#line 1960 "go.y"
+#line 1962 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
importsym((yyvsp[(1) - (1)].sym), OTYPE);
@@ -5141,18 +4621,14 @@ yyreduce:
break;
case 317:
-
-/* Line 1806 of yacc.c */
-#line 1980 "go.y"
+#line 1982 "go.y"
{
(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
}
break;
case 318:
-
-/* Line 1806 of yacc.c */
-#line 1984 "go.y"
+#line 1986 "go.y"
{
// predefined name like uint8
(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
@@ -5165,63 +4641,49 @@ yyreduce:
break;
case 319:
-
-/* Line 1806 of yacc.c */
-#line 1994 "go.y"
+#line 1996 "go.y"
{
(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
}
break;
case 320:
-
-/* Line 1806 of yacc.c */
-#line 1998 "go.y"
+#line 2000 "go.y"
{
(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
}
break;
case 321:
-
-/* Line 1806 of yacc.c */
-#line 2002 "go.y"
+#line 2004 "go.y"
{
(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
}
break;
case 322:
-
-/* Line 1806 of yacc.c */
-#line 2006 "go.y"
+#line 2008 "go.y"
{
(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
}
break;
case 323:
-
-/* Line 1806 of yacc.c */
-#line 2010 "go.y"
+#line 2012 "go.y"
{
(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
}
break;
case 324:
-
-/* Line 1806 of yacc.c */
-#line 2014 "go.y"
+#line 2016 "go.y"
{
(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
}
break;
case 325:
-
-/* Line 1806 of yacc.c */
-#line 2018 "go.y"
+#line 2020 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(2) - (2)].type);
@@ -5230,9 +4692,7 @@ yyreduce:
break;
case 326:
-
-/* Line 1806 of yacc.c */
-#line 2024 "go.y"
+#line 2026 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (4)].type);
@@ -5241,9 +4701,7 @@ yyreduce:
break;
case 327:
-
-/* Line 1806 of yacc.c */
-#line 2030 "go.y"
+#line 2032 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -5252,9 +4710,7 @@ yyreduce:
break;
case 328:
-
-/* Line 1806 of yacc.c */
-#line 2038 "go.y"
+#line 2040 "go.y"
{
(yyval.type) = typ(TCHAN);
(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -5263,18 +4719,14 @@ yyreduce:
break;
case 329:
-
-/* Line 1806 of yacc.c */
-#line 2046 "go.y"
+#line 2048 "go.y"
{
(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
}
break;
case 330:
-
-/* Line 1806 of yacc.c */
-#line 2052 "go.y"
+#line 2054 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
if((yyvsp[(1) - (3)].sym))
@@ -5284,9 +4736,7 @@ yyreduce:
break;
case 331:
-
-/* Line 1806 of yacc.c */
-#line 2059 "go.y"
+#line 2061 "go.y"
{
Type *t;
@@ -5303,9 +4753,7 @@ yyreduce:
break;
case 332:
-
-/* Line 1806 of yacc.c */
-#line 2075 "go.y"
+#line 2077 "go.y"
{
Sym *s;
Pkg *p;
@@ -5328,63 +4776,49 @@ yyreduce:
break;
case 333:
-
-/* Line 1806 of yacc.c */
-#line 2097 "go.y"
+#line 2099 "go.y"
{
(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
}
break;
case 334:
-
-/* Line 1806 of yacc.c */
-#line 2101 "go.y"
+#line 2103 "go.y"
{
(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
}
break;
case 335:
-
-/* Line 1806 of yacc.c */
-#line 2106 "go.y"
+#line 2108 "go.y"
{
(yyval.list) = nil;
}
break;
case 337:
-
-/* Line 1806 of yacc.c */
-#line 2113 "go.y"
+#line 2115 "go.y"
{
(yyval.list) = (yyvsp[(2) - (3)].list);
}
break;
case 338:
-
-/* Line 1806 of yacc.c */
-#line 2117 "go.y"
+#line 2119 "go.y"
{
(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
}
break;
case 339:
-
-/* Line 1806 of yacc.c */
-#line 2127 "go.y"
+#line 2129 "go.y"
{
(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
}
break;
case 340:
-
-/* Line 1806 of yacc.c */
-#line 2131 "go.y"
+#line 2133 "go.y"
{
(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
switch((yyval.node)->val.ctype){
@@ -5395,6 +4829,10 @@ yyreduce:
case CTFLT:
mpnegflt((yyval.node)->val.u.fval);
break;
+ case CTCPLX:
+ mpnegflt(&(yyval.node)->val.u.cval->real);
+ mpnegflt(&(yyval.node)->val.u.cval->imag);
+ break;
default:
yyerror("bad negated constant");
}
@@ -5402,9 +4840,7 @@ yyreduce:
break;
case 341:
-
-/* Line 1806 of yacc.c */
-#line 2146 "go.y"
+#line 2152 "go.y"
{
(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
if((yyval.node)->op != OLITERAL)
@@ -5413,9 +4849,7 @@ yyreduce:
break;
case 343:
-
-/* Line 1806 of yacc.c */
-#line 2155 "go.y"
+#line 2161 "go.y"
{
if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
(yyval.node) = (yyvsp[(2) - (5)].node);
@@ -5429,76 +4863,52 @@ yyreduce:
break;
case 346:
-
-/* Line 1806 of yacc.c */
-#line 2171 "go.y"
+#line 2177 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 347:
-
-/* Line 1806 of yacc.c */
-#line 2175 "go.y"
+#line 2181 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 348:
-
-/* Line 1806 of yacc.c */
-#line 2181 "go.y"
+#line 2187 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 349:
-
-/* Line 1806 of yacc.c */
-#line 2185 "go.y"
+#line 2191 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
case 350:
-
-/* Line 1806 of yacc.c */
-#line 2191 "go.y"
+#line 2197 "go.y"
{
(yyval.list) = list1((yyvsp[(1) - (1)].node));
}
break;
case 351:
-
-/* Line 1806 of yacc.c */
-#line 2195 "go.y"
+#line 2201 "go.y"
{
(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
}
break;
-
-/* Line 1806 of yacc.c */
-#line 5490 "y.tab.c"
+/* Line 1267 of yacc.c. */
+#line 4911 "y.tab.c"
default: break;
}
- /* User semantic actions sometimes alter yychar, and that requires
- that yytoken be updated with the new translation. We take the
- approach of translating immediately before every use of yytoken.
- One alternative is translating here after every semantic action,
- but that translation would be missed if the semantic action invokes
- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
- incorrect destructor might then be invoked immediately. In the
- case of YYERROR or YYBACKUP, subsequent parser actions might lead
- to an incorrect destructor call or verbose syntax error message
- before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@@ -5507,6 +4917,7 @@ yyreduce:
*++yyvsp = yyval;
+
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
@@ -5526,10 +4937,6 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@@ -5537,36 +4944,37 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
- yyssp, yytoken)
{
- char *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = YYSYNTAX_ERROR;
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == 1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
- if (!yymsg)
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = 2;
- }
- else
- {
- yysyntax_error_status = YYSYNTAX_ERROR;
- yymsgp = yymsg;
- }
- }
- yyerror (yymsgp);
- if (yysyntax_error_status == 2)
- goto yyexhaustedlab;
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
}
-# undef YYSYNTAX_ERROR
#endif
}
@@ -5574,7 +4982,7 @@ yyerrlab:
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
@@ -5591,7 +4999,7 @@ yyerrlab:
}
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
@@ -5625,7 +5033,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
- if (!yypact_value_is_default (yyn))
+ if (yyn != YYPACT_NINF)
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -5648,6 +5056,9 @@ yyerrlab1:
YY_STACK_PRINT (yyss, yyssp);
}
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
*++yyvsp = yylval;
@@ -5672,7 +5083,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#ifndef yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -5683,14 +5094,9 @@ yyexhaustedlab:
#endif
yyreturn:
- if (yychar != YYEMPTY)
- {
- /* Make sure we have latest lookahead translation. See comments at
- user semantic actions for why this is necessary. */
- yytoken = YYTRANSLATE (yychar);
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
- }
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@@ -5714,9 +5120,7 @@ yyreturn:
}
-
-/* Line 2067 of yacc.c */
-#line 2199 "go.y"
+#line 2205 "go.y"
static void
diff --git a/src/cmd/gc/y.tab.h b/src/cmd/gc/y.tab.h
index 6eeb831b2..d01fbe198 100644
--- a/src/cmd/gc/y.tab.h
+++ b/src/cmd/gc/y.tab.h
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Bison interface for Yacc-like parsers in C
-
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -26,11 +29,10 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
-
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -144,28 +146,22 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-{
-
-/* Line 2068 of yacc.c */
#line 28 "go.y"
-
+{
Node* node;
NodeList* list;
Type* type;
Sym* sym;
struct Val val;
int i;
-
-
-
-/* Line 2068 of yacc.c */
-#line 163 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1529 of yacc.c. */
+#line 160 "y.tab.h"
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
-
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index f70f778d9..3645f1c2d 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -5,6 +5,7 @@
package main
import (
+ "bufio"
"bytes"
"container/heap"
"errors"
@@ -27,7 +28,7 @@ import (
)
var cmdBuild = &Command{
- UsageLine: "build [-o output] [build flags] [packages]",
+ UsageLine: "build [-o output] [-i] [build flags] [packages]",
Short: "compile packages and dependencies",
Long: `
Build compiles the packages named by the import paths,
@@ -49,7 +50,10 @@ derives from the first file name mentioned, such as f1 for 'go build
f1.go f2.go'; with no files provided ('go build'), the output file
name is the base name of the containing directory.
-The build flags are shared by the build, install, run, and test commands:
+The -i flag installs the packages that are dependencies of the target.
+
+The build flags are shared by the build, clean, get, install, list, run,
+and test commands:
-a
force rebuilding of packages that are already up-to-date.
@@ -86,8 +90,8 @@ The build flags are shared by the build, install, run, and test commands:
arguments to pass on each 5l, 6l, or 8l linker invocation.
-tags 'tag list'
a list of build tags to consider satisfied during the build.
- See the documentation for the go/build package for
- more information about build tags.
+ For more information about build tags, see the description of
+ build constraints in the documentation for the go/build package.
The list flags accept a space-separated list of strings. To embed spaces
in an element in the list, surround it with either single or double quotes.
@@ -106,6 +110,8 @@ func init() {
cmdBuild.Run = runBuild
cmdInstall.Run = runInstall
+ cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
+
addBuildFlags(cmdBuild)
addBuildFlags(cmdInstall)
}
@@ -116,6 +122,7 @@ var buildN bool // -n flag
var buildP = runtime.NumCPU() // -p flag
var buildV bool // -v flag
var buildX bool // -x flag
+var buildI bool // -i flag
var buildO = cmdBuild.Flag.String("o", "", "output file")
var buildWork bool // -work flag
var buildGcflags []string // -gcflags flag
@@ -158,7 +165,8 @@ func init() {
}
}
-// addBuildFlags adds the flags common to the build and install commands.
+// addBuildFlags adds the flags common to the build, clean, get,
+// install, list, run, and test commands.
func addBuildFlags(cmd *Command) {
// NOTE: If you add flags here, also add them to testflag.go.
cmd.Flag.BoolVar(&buildA, "a", false, "")
@@ -203,6 +211,9 @@ type stringsFlag []string
func (v *stringsFlag) Set(s string) error {
var err error
*v, err = splitQuotedFields(s)
+ if *v == nil {
+ *v = []string{}
+ }
return err
}
@@ -286,8 +297,12 @@ func runBuild(cmd *Command, args []string) {
}
a := &action{}
+ depMode := modeBuild
+ if buildI {
+ depMode = modeInstall
+ }
for _, p := range packages(args) {
- a.deps = append(a.deps, b.action(modeBuild, modeBuild, p))
+ a.deps = append(a.deps, b.action(modeBuild, depMode, p))
}
b.do(a)
}
@@ -349,7 +364,12 @@ func init() {
var err error
archChar, err = build.ArchChar(goarch)
if err != nil {
- fatalf("%s", err)
+ if _, isgc := buildToolchain.(gcToolchain); isgc {
+ fatalf("%s", err)
+ }
+ // archChar is only required for gcToolchain, if we're using
+ // another toolchain leave it blank.
+ archChar = ""
}
}
@@ -438,7 +458,8 @@ func (b *builder) init() {
fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
}
if !buildWork {
- atexit(func() { os.RemoveAll(b.work) })
+ workdir := b.work
+ atexit(func() { os.RemoveAll(workdir) })
}
}
}
@@ -760,6 +781,11 @@ func (b *builder) build(a *action) (err error) {
return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
}
+ // Same as above for Objective-C files
+ if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
+ return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
+ a.p.ImportPath, strings.Join(a.p.MFiles, ","))
+ }
defer func() {
if err != nil && err != errPrintedOutput {
err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
@@ -799,25 +825,7 @@ func (b *builder) build(a *action) (err error) {
var gofiles, cfiles, sfiles, objects, cgoObjects []string
- // If we're doing coverage, preprocess the .go files and put them in the work directory
- if a.p.coverMode != "" {
- for _, file := range a.p.GoFiles {
- sourceFile := filepath.Join(a.p.Dir, file)
- cover := a.p.coverVars[file]
- if cover == nil || isTestFile(file) {
- // Not covering this file.
- gofiles = append(gofiles, file)
- continue
- }
- coverFile := filepath.Join(obj, file)
- if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
- return err
- }
- gofiles = append(gofiles, coverFile)
- }
- } else {
- gofiles = append(gofiles, a.p.GoFiles...)
- }
+ gofiles = append(gofiles, a.p.GoFiles...)
cfiles = append(cfiles, a.p.CFiles...)
sfiles = append(sfiles, a.p.SFiles...)
@@ -851,7 +859,7 @@ func (b *builder) build(a *action) (err error) {
if a.cgo != nil && a.cgo.target != "" {
cgoExe = a.cgo.target
}
- outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles)
+ outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
if err != nil {
return err
}
@@ -866,7 +874,7 @@ func (b *builder) build(a *action) (err error) {
gccfiles := append(cfiles, sfiles...)
cfiles = nil
sfiles = nil
- outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles)
+ outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
if err != nil {
return err
}
@@ -874,21 +882,54 @@ func (b *builder) build(a *action) (err error) {
gofiles = append(gofiles, outGo...)
}
+ if len(gofiles) == 0 {
+ return &build.NoGoError{a.p.Dir}
+ }
+
+ // If we're doing coverage, preprocess the .go files and put them in the work directory
+ if a.p.coverMode != "" {
+ for i, file := range gofiles {
+ var sourceFile string
+ var coverFile string
+ var key string
+ if strings.HasSuffix(file, ".cgo1.go") {
+ // cgo files have absolute paths
+ base := filepath.Base(file)
+ sourceFile = file
+ coverFile = filepath.Join(obj, base)
+ key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
+ } else {
+ sourceFile = filepath.Join(a.p.Dir, file)
+ coverFile = filepath.Join(obj, file)
+ key = file
+ }
+ cover := a.p.coverVars[key]
+ if cover == nil || isTestFile(file) {
+ // Not covering this file.
+ continue
+ }
+ if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
+ return err
+ }
+ gofiles[i] = coverFile
+ }
+ }
+
// Prepare Go import path list.
inc := b.includeArgs("-I", a.deps)
// Compile Go.
- if len(gofiles) > 0 {
- ofile, out, err := buildToolchain.gc(b, a.p, obj, inc, gofiles)
- if len(out) > 0 {
- b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
- if err != nil {
- return errPrintedOutput
- }
- }
+ ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, inc, gofiles)
+ if len(out) > 0 {
+ b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
if err != nil {
- return err
+ return errPrintedOutput
}
+ }
+ if err != nil {
+ return err
+ }
+ if ofile != a.objpkg {
objects = append(objects, ofile)
}
@@ -903,17 +944,17 @@ func (b *builder) build(a *action) (err error) {
switch {
case strings.HasSuffix(name, _goos_goarch):
targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
- if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
+ if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
return err
}
case strings.HasSuffix(name, _goarch):
targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
- if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
+ if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
return err
}
case strings.HasSuffix(name, _goos):
targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
- if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
+ if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
return err
}
}
@@ -952,9 +993,15 @@ func (b *builder) build(a *action) (err error) {
objects = append(objects, filepath.Join(a.p.Dir, syso))
}
- // Pack into archive in obj directory
- if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
- return err
+ // Pack into archive in obj directory.
+ // If the Go compiler wrote an archive, we only need to add the
+ // object files for non-Go sources to the archive.
+ // If the Go compiler wrote an archive and the package is entirely
+ // Go sources, there is no pack to execute at all.
+ if len(objects) > 0 {
+ if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
+ return err
+ }
}
// Link if needed.
@@ -979,9 +1026,9 @@ func (b *builder) install(a *action) (err error) {
}
}()
a1 := a.deps[0]
- perm := os.FileMode(0666)
+ perm := os.FileMode(0644)
if a1.link {
- perm = 0777
+ perm = 0755
}
// make target directory
@@ -1001,22 +1048,7 @@ func (b *builder) install(a *action) (err error) {
defer os.Remove(a1.target)
}
- if a.p.usesSwig() {
- for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
- dir = a.p.swigDir(&buildContext)
- if err := b.mkdir(dir); err != nil {
- return err
- }
- soname := a.p.swigSoname(f)
- source := filepath.Join(a.objdir, soname)
- target := filepath.Join(dir, soname)
- if err = b.copyFile(a, target, source, perm); err != nil {
- return err
- }
- }
- }
-
- return b.copyFile(a, a.target, a1.target, perm)
+ return b.moveOrCopyFile(a, a.target, a1.target, perm)
}
// includeArgs returns the -I or -L directory list for access
@@ -1062,6 +1094,27 @@ func (b *builder) includeArgs(flag string, all []*action) []string {
return inc
}
+// moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
+func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
+ if buildN {
+ b.showcmd("", "mv %s %s", src, dst)
+ return nil
+ }
+
+ // If we can update the mode and rename to the dst, do it.
+ // Otherwise fall back to standard copy.
+ if err := os.Chmod(src, perm); err == nil {
+ if err := os.Rename(src, dst); err == nil {
+ if buildX {
+ b.showcmd("", "mv %s %s", src, dst)
+ }
+ return nil
+ }
+ }
+
+ return b.copyFile(a, dst, src, perm)
+}
+
// copyFile is like 'cp src dst'.
func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
if buildN || buildX {
@@ -1262,6 +1315,7 @@ func relPaths(paths []string) []string {
var errPrintedOutput = errors.New("already printed output - no need to show error")
var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
+var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
// run runs the command given by cmdline in the directory dir.
// If the command fails, run prints information about the failure
@@ -1288,11 +1342,11 @@ func (b *builder) processOutput(out []byte) string {
messages := string(out)
// Fix up output referring to cgo-generated code to be more readable.
// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
- // Replace _Ctype_foo with C.foo.
+ // Replace *[100]_Ctype_foo with *[100]C.foo.
// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
if !buildX && cgoLine.MatchString(messages) {
messages = cgoLine.ReplaceAllString(messages, "")
- messages = strings.Replace(messages, "type _Ctype_", "type C.", -1)
+ messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
}
return messages
}
@@ -1302,7 +1356,13 @@ func (b *builder) processOutput(out []byte) string {
func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
cmdline := stringList(cmdargs...)
if buildN || buildX {
- b.showcmd(dir, "%s", joinUnambiguously(cmdline))
+ var envcmdline string
+ for i := range env {
+ envcmdline += env[i]
+ envcmdline += " "
+ }
+ envcmdline += joinUnambiguously(cmdline)
+ b.showcmd(dir, "%s", envcmdline)
if buildN {
return nil, nil
}
@@ -1432,7 +1492,7 @@ type toolchain interface {
// gc runs the compiler in a specific directory on a set of files
// and returns the name of the generated output file.
// The compiler runs in the directory dir.
- gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
+ gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
// cc runs the toolchain's C compiler in a directory on a C file
// to produce an output file.
cc(b *builder, p *Package, objdir, ofile, cfile string) error
@@ -1469,7 +1529,7 @@ func (noToolchain) linker() string {
return ""
}
-func (noToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
+func (noToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
return "", nil, noCompiler()
}
@@ -1505,9 +1565,14 @@ func (gcToolchain) linker() string {
return tool(archChar + "l")
}
-func (gcToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
- out := "_go_." + archChar
- ofile = obj + out
+func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+ if archive != "" {
+ ofile = archive
+ } else {
+ out := "_go_." + archChar
+ ofile = obj + out
+ }
+
gcargs := []string{"-p", p.ImportPath}
if p.Standard && p.ImportPath == "runtime" {
// runtime compiles with a special 6g flag to emit
@@ -1519,7 +1584,7 @@ func (gcToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
// so that it can give good error messages about forward declarations.
// Exceptions: a few standard packages have forward declarations for
// pieces supplied behind-the-scenes by package runtime.
- extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
+ extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
if p.Standard {
switch p.ImportPath {
case "os", "runtime/pprof", "sync", "time":
@@ -1533,7 +1598,10 @@ func (gcToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
}
- args := stringList(tool(archChar+"g"), "-o", ofile, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
+ args := stringList(tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
+ if ofile == archive {
+ args = append(args, "-pack")
+ }
for _, f := range gofiles {
args = append(args, mkAbs(p.Dir, f))
}
@@ -1544,7 +1612,7 @@ func (gcToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
sfile = mkAbs(p.Dir, sfile)
- return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-I", obj, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
+ return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
}
func (gcToolchain) pkgpath(basedir string, p *Package) string {
@@ -1557,83 +1625,148 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
for _, f := range ofiles {
absOfiles = append(absOfiles, mkAbs(objDir, f))
}
- return b.run(p.Dir, p.ImportPath, nil, tool("pack"), "grcP", b.work, mkAbs(objDir, afile), absOfiles)
+ cmd := "c"
+ absAfile := mkAbs(objDir, afile)
+ appending := false
+ if _, err := os.Stat(absAfile); err == nil {
+ appending = true
+ cmd = "r"
+ }
+
+ cmdline := stringList("pack", cmd, absAfile, absOfiles)
+
+ if appending {
+ if buildN || buildX {
+ b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
+ }
+ if buildN {
+ return nil
+ }
+ if err := packInternal(b, absAfile, absOfiles); err != nil {
+ b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
+ return errPrintedOutput
+ }
+ return nil
+ }
+
+ // Need actual pack.
+ cmdline[0] = tool("pack")
+ return b.run(p.Dir, p.ImportPath, nil, cmdline)
+}
+
+func packInternal(b *builder, afile string, ofiles []string) error {
+ dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
+ if err != nil {
+ return err
+ }
+ defer dst.Close() // only for error returns or panics
+ w := bufio.NewWriter(dst)
+
+ for _, ofile := range ofiles {
+ src, err := os.Open(ofile)
+ if err != nil {
+ return err
+ }
+ fi, err := src.Stat()
+ if err != nil {
+ src.Close()
+ return err
+ }
+ // Note: Not using %-16.16s format because we care
+ // about bytes, not runes.
+ name := fi.Name()
+ if len(name) > 16 {
+ name = name[:16]
+ } else {
+ name += strings.Repeat(" ", 16-len(name))
+ }
+ size := fi.Size()
+ fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
+ name, 0, 0, 0, 0644, size)
+ n, err := io.Copy(w, src)
+ src.Close()
+ if err == nil && n < size {
+ err = io.ErrUnexpectedEOF
+ } else if err == nil && n > size {
+ err = fmt.Errorf("file larger than size reported by stat")
+ }
+ if err != nil {
+ return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
+ }
+ if size&1 != 0 {
+ w.WriteByte(0)
+ }
+ }
+
+ if err := w.Flush(); err != nil {
+ return err
+ }
+ return dst.Close()
}
func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
importArgs := b.includeArgs("-L", allactions)
- swigDirs := make(map[string]bool)
- swigArg := []string{}
cxx := false
for _, a := range allactions {
- if a.p != nil && a.p.usesSwig() {
- sd := a.p.swigDir(&buildContext)
- if len(swigArg) == 0 {
- swigArg = []string{"-r", sd}
- } else if !swigDirs[sd] {
- swigArg[1] += ":"
- swigArg[1] += sd
- }
- swigDirs[sd] = true
- if a.objdir != "" && !swigDirs[a.objdir] {
- swigArg[1] += ":"
- swigArg[1] += a.objdir
- swigDirs[a.objdir] = true
- }
- }
if a.p != nil && len(a.p.CXXFiles) > 0 {
cxx = true
}
}
ldflags := buildLdflags
+ // Limit slice capacity so that concurrent appends do not race on the shared array.
+ ldflags = ldflags[:len(ldflags):len(ldflags)]
if buildContext.InstallSuffix != "" {
ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
}
- if cxx {
- // The program includes C++ code. If the user has not
- // specified the -extld option, then default to
- // linking with the compiler named by the CXX
- // environment variable, or g++ if CXX is not set.
- extld := false
- for _, f := range ldflags {
- if f == "-extld" || strings.HasPrefix(f, "-extld=") {
- extld = true
- break
- }
+ if p.omitDWARF {
+ ldflags = append(ldflags, "-w")
+ }
+
+ // If the user has not specified the -extld option, then specify the
+ // appropriate linker. In case of C++ code, use the compiler named
+ // by the CXX environment variable or defaultCXX if CXX is not set.
+ // Else, use the CC environment variable and defaultCC as fallback.
+ extld := false
+ for _, f := range ldflags {
+ if f == "-extld" || strings.HasPrefix(f, "-extld=") {
+ extld = true
+ break
}
- if !extld {
- compiler := strings.Fields(os.Getenv("CXX"))
- if len(compiler) == 0 {
- compiler = []string{"g++"}
- }
- ldflags = append(ldflags, "-extld="+compiler[0])
- if len(compiler) > 1 {
- extldflags := false
- add := strings.Join(compiler[1:], " ")
- for i, f := range ldflags {
- if f == "-extldflags" && i+1 < len(ldflags) {
- ldflags[i+1] = add + " " + ldflags[i+1]
- extldflags = true
- break
- } else if strings.HasPrefix(f, "-extldflags=") {
- ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
- extldflags = true
- break
- }
- }
- if !extldflags {
- ldflags = append(ldflags, "-extldflags="+add)
+ }
+ if !extld {
+ var compiler []string
+ if cxx {
+ compiler = envList("CXX", defaultCXX)
+ } else {
+ compiler = envList("CC", defaultCC)
+ }
+ ldflags = append(ldflags, "-extld="+compiler[0])
+ if len(compiler) > 1 {
+ extldflags := false
+ add := strings.Join(compiler[1:], " ")
+ for i, f := range ldflags {
+ if f == "-extldflags" && i+1 < len(ldflags) {
+ ldflags[i+1] = add + " " + ldflags[i+1]
+ extldflags = true
+ break
+ } else if strings.HasPrefix(f, "-extldflags=") {
+ ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
+ extldflags = true
+ break
}
}
+ if !extldflags {
+ ldflags = append(ldflags, "-extldflags="+add)
+ }
}
}
- return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, swigArg, ldflags, mainpkg)
+ return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
}
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
cfile = mkAbs(p.Dir, cfile)
- args := stringList(tool(archChar+"c"), "-F", "-V", "-w", "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
+ args := stringList(tool(archChar+"c"), "-F", "-V", "-w", "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
return b.run(p.Dir, p.ImportPath, nil, args)
}
@@ -1650,7 +1783,7 @@ func (gccgoToolchain) linker() string {
return gccgoBin
}
-func (gccgoToolchain) gc(b *builder, p *Package, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
+func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
out := p.Name + ".o"
ofile = obj + out
gcargs := []string{"-g"}
@@ -1698,52 +1831,62 @@ func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles
func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
// gccgo needs explicit linking with all package dependencies,
// and all LDFLAGS from cgo dependencies.
- afiles := make(map[*Package]string)
- sfiles := make(map[*Package][]string)
+ apackagesSeen := make(map[*Package]bool)
+ afiles := []string{}
ldflags := b.gccArchArgs()
cgoldflags := []string{}
usesCgo := false
cxx := false
- for _, a := range allactions {
- if a.p != nil {
- if !a.p.Standard {
- if afiles[a.p] == "" || a.objpkg != a.target {
- afiles[a.p] = a.target
+ objc := false
+
+ // Prefer the output of an install action to the output of a build action,
+ // because the install action will delete the output of the build action.
+ // Iterate over the list backward (reverse dependency order) so that we
+ // always see the install before the build.
+ for i := len(allactions) - 1; i >= 0; i-- {
+ a := allactions[i]
+ if !a.p.Standard {
+ if a.p != nil && !apackagesSeen[a.p] {
+ apackagesSeen[a.p] = true
+ if a.p.fake {
+ // move _test files to the top of the link order
+ afiles = append([]string{a.target}, afiles...)
+ } else {
+ afiles = append(afiles, a.target)
}
}
+ }
+ }
+
+ for _, a := range allactions {
+ if a.p != nil {
cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
if len(a.p.CgoFiles) > 0 {
usesCgo = true
}
if a.p.usesSwig() {
- sd := a.p.swigDir(&buildContext)
- if a.objdir != "" {
- sd = a.objdir
- }
- for _, f := range stringList(a.p.SwigFiles, a.p.SwigCXXFiles) {
- soname := a.p.swigSoname(f)
- sfiles[a.p] = append(sfiles[a.p], filepath.Join(sd, soname))
- }
usesCgo = true
}
if len(a.p.CXXFiles) > 0 {
cxx = true
}
+ if len(a.p.MFiles) > 0 {
+ objc = true
+ }
}
}
- for _, afile := range afiles {
- ldflags = append(ldflags, afile)
- }
- for _, sfiles := range sfiles {
- ldflags = append(ldflags, sfiles...)
- }
+ ldflags = append(ldflags, afiles...)
ldflags = append(ldflags, cgoldflags...)
+ ldflags = append(ldflags, p.CgoLDFLAGS...)
if usesCgo && goos == "linux" {
ldflags = append(ldflags, "-Wl,-E")
}
if cxx {
ldflags = append(ldflags, "-lstdc++")
}
+ if objc {
+ ldflags = append(ldflags, "-lobjc")
+ }
return b.run(".", p.ImportPath, nil, "gccgo", "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
}
@@ -1856,16 +1999,13 @@ func (b *builder) gxxCmd(objdir string) []string {
}
// ccompilerCmd returns a command line prefix for the given environment
-// variable and using the default command when the variable is empty
+// variable and using the default command when the variable is empty.
func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
// NOTE: env.go's mkEnv knows that the first three
// strings returned are "gcc", "-I", objdir (and cuts them off).
- compiler := strings.Fields(os.Getenv(envvar))
- if len(compiler) == 0 {
- compiler = strings.Fields(defcmd)
- }
- a := []string{compiler[0], "-I", objdir, "-g", "-O2"}
+ compiler := envList(envvar, defcmd)
+ a := []string{compiler[0], "-I", objdir}
a = append(a, compiler[1:]...)
// Definitely want -fPIC but on Windows gcc complains
@@ -1892,6 +2032,9 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
a = append(a, "-Qunused-arguments")
}
+ // disable word wrapping in error messages
+ a = append(a, "-fmessage-length=0")
+
// On OS X, some of the compilers behave as if -fno-common
// is always set, and the Mach-O linker in 6l/8l assumes this.
// See http://golang.org/issue/3253.
@@ -1915,8 +2058,28 @@ func (b *builder) gccArchArgs() []string {
return nil
}
-func envList(key string) []string {
- return strings.Fields(os.Getenv(key))
+// envList returns the value of the given environment variable broken
+// into fields, using the default value when the variable is empty.
+func envList(key, def string) []string {
+ v := os.Getenv(key)
+ if v == "" {
+ v = def
+ }
+ return strings.Fields(v)
+}
+
+// Return the flags to use when invoking the C or C++ compilers, or cgo.
+func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
+ var defaults string
+ if def {
+ defaults = "-g -O2"
+ }
+
+ cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
+ cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
+ cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
+ ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
+ return
}
var cgoRe = regexp.MustCompile(`[/\\:]`)
@@ -1927,15 +2090,14 @@ var (
cgoLibGccFileOnce sync.Once
)
-func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfiles []string) (outGo, outObj []string, err error) {
- if goos != toolGOOS {
- return nil, nil, errors.New("cannot use cgo when compiling for a different operating system")
- }
+func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+ cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
+ _, cgoexeCFLAGS, _, _ := b.cflags(p, false)
- cgoCPPFLAGS := stringList(envList("CGO_CPPFLAGS"), p.CgoCPPFLAGS)
- cgoCFLAGS := stringList(envList("CGO_CFLAGS"), p.CgoCFLAGS)
- cgoCXXFLAGS := stringList(envList("CGO_CXXFLAGS"), p.CgoCXXFLAGS)
- cgoLDFLAGS := stringList(envList("CGO_LDFLAGS"), p.CgoLDFLAGS)
+ // If we are compiling Objective-C code, then we need to link against libobjc
+ if len(mfiles) > 0 {
+ cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
+ }
if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
out, err := b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
@@ -2001,7 +2163,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfile
}
objExt = "o"
}
- if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, p.CgoFiles); err != nil {
+ if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
return nil, nil, err
}
outGo = append(outGo, gofiles...)
@@ -2088,6 +2250,16 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfile
outObj = append(outObj, ofile)
}
+ for _, file := range mfiles {
+ // Append .o to the file, just in case the pkg has file.c and file.m
+ ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
+ if err := b.gcc(p, ofile, cflags, file); err != nil {
+ return nil, nil, err
+ }
+ linkobj = append(linkobj, ofile)
+ outObj = append(outObj, ofile)
+ }
+
linkobj = append(linkobj, p.SysoFiles...)
dynobj := obj + "_cgo_.o"
if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
@@ -2145,24 +2317,39 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string, gxxfile
// Run SWIG on all SWIG input files.
// TODO: Don't build a shared library, once SWIG emits the necessary
// pragmas for external linking.
-func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles []string) (outGo, outObj []string, err error) {
+func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+ cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
+ cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
+ cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
- var extraObj []string
for _, file := range gccfiles {
ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
- if err := b.gcc(p, ofile, nil, file); err != nil {
+ if err := b.gcc(p, ofile, cflags, file); err != nil {
return nil, nil, err
}
- extraObj = append(extraObj, ofile)
+ outObj = append(outObj, ofile)
}
for _, file := range gxxfiles {
// Append .o to the file, just in case the pkg has file.c and file.cpp
ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
- if err := b.gxx(p, ofile, nil, file); err != nil {
+ if err := b.gxx(p, ofile, cxxflags, file); err != nil {
return nil, nil, err
}
- extraObj = append(extraObj, ofile)
+ outObj = append(outObj, ofile)
+ }
+
+ for _, file := range mfiles {
+ // Append .o to the file, just in case the pkg has file.c and file.cpp
+ ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
+ if err := b.gcc(p, ofile, cflags, file); err != nil {
+ return nil, nil, err
+ }
+ outObj = append(outObj, ofile)
+ }
+
+ if err := b.swigVersionCheck(); err != nil {
+ return nil, nil, err
}
intgosize, err := b.swigIntSize(obj)
@@ -2171,7 +2358,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles []string) (out
}
for _, f := range p.SwigFiles {
- goFile, objFile, err := b.swigOne(p, f, obj, false, intgosize, extraObj)
+ goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, false, intgosize)
if err != nil {
return nil, nil, err
}
@@ -2181,9 +2368,12 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles []string) (out
if objFile != "" {
outObj = append(outObj, objFile)
}
+ if gccObjFile != "" {
+ outObj = append(outObj, gccObjFile)
+ }
}
for _, f := range p.SwigCXXFiles {
- goFile, objFile, err := b.swigOne(p, f, obj, true, intgosize, extraObj)
+ goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, true, intgosize)
if err != nil {
return nil, nil, err
}
@@ -2193,10 +2383,48 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles []string) (out
if objFile != "" {
outObj = append(outObj, objFile)
}
+ if gccObjFile != "" {
+ outObj = append(outObj, gccObjFile)
+ }
}
return outGo, outObj, nil
}
+// Make sure SWIG is new enough.
+var (
+ swigCheckOnce sync.Once
+ swigCheck error
+)
+
+func (b *builder) swigDoVersionCheck() error {
+ out, err := b.runOut("", "", nil, "swig", "-version")
+ if err != nil {
+ return err
+ }
+ re := regexp.MustCompile(`[vV]ersion +([\d])`)
+ matches := re.FindSubmatch(out)
+ if matches == nil {
+ // Can't find version number; hope for the best.
+ return nil
+ }
+ major, err := strconv.Atoi(string(matches[1]))
+ if err != nil {
+ // Can't find version number; hope for the best.
+ return nil
+ }
+ if major < 3 {
+ return errors.New("must have SWIG version >= 3.0")
+ }
+ return nil
+}
+
+func (b *builder) swigVersionCheck() error {
+ swigCheckOnce.Do(func() {
+ swigCheck = b.swigDoVersionCheck()
+ })
+ return swigCheck
+}
+
// This code fails to build if sizeof(int) <= 32
const swigIntSizeCode = `
package main
@@ -2217,14 +2445,22 @@ func (b *builder) swigIntSize(obj string) (intsize string, err error) {
p := goFilesPackage(srcs)
- if _, _, e := buildToolchain.gc(b, p, obj, nil, srcs); e != nil {
+ if _, _, e := buildToolchain.gc(b, p, "", obj, nil, srcs); e != nil {
return "32", nil
}
return "64", nil
}
// Run SWIG on one SWIG input file.
-func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string, extraObj []string) (outGo, outObj string, err error) {
+func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
+ cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
+ var cflags []string
+ if cxx {
+ cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS)
+ } else {
+ cflags = stringList(cgoCPPFLAGS, cgoCFLAGS)
+ }
+
n := 5 // length of ".swig"
if cxx {
n = 8 // length of ".swigcxx"
@@ -2237,7 +2473,6 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
if cxx {
gccExt = "cxx"
}
- soname := p.swigSoname(file)
_, gccgo := buildToolchain.(gccgoToolchain)
@@ -2246,12 +2481,14 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
"-go",
"-intgosize", intgosize,
"-module", base,
- "-soname", soname,
"-o", obj + gccBase + gccExt,
"-outdir", obj,
}
if gccgo {
args = append(args, "-gccgo")
+ if pkgpath := gccgoPkgpath(p); pkgpath != "" {
+ args = append(args, "-go-pkgpath", pkgpath)
+ }
}
if cxx {
args = append(args, "-c++")
@@ -2260,12 +2497,12 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
if len(out) > 0 {
if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
- return "", "", errors.New("must have SWIG version >= 2.0.9\n")
+ return "", "", "", errors.New("must have SWIG version >= 3.0")
}
b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
- return "", "", errPrintedOutput
+ return "", "", "", errPrintedOutput
}
- return "", "", err
+ return "", "", "", err
}
var cObj string
@@ -2273,32 +2510,23 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
// cc
cObj = obj + cBase + archChar
if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
- return "", "", err
+ return "", "", "", err
}
}
// gcc
gccObj := obj + gccBase + "o"
- if err := b.gcc(p, gccObj, []string{"-g", "-fPIC", "-O2"}, obj+gccBase+gccExt); err != nil {
- return "", "", err
- }
-
- // create shared library
- osldflags := map[string][]string{
- "darwin": {"-dynamiclib", "-Wl,-undefined,dynamic_lookup"},
- "freebsd": {"-shared", "-lpthread", "-lm"},
- "linux": {"-shared", "-lpthread", "-lm"},
- "windows": {"-shared", "-lm", "-mthreads"},
- }
- var cxxlib []string
- if cxx {
- cxxlib = []string{"-lstdc++"}
+ if !cxx {
+ if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
+ return "", "", "", err
+ }
+ } else {
+ if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
+ return "", "", "", err
+ }
}
- ldflags := stringList(osldflags[goos], cxxlib)
- target := filepath.Join(obj, soname)
- b.run(p.Dir, p.ImportPath, nil, b.gccCmd(p.Dir), "-o", target, gccObj, extraObj, ldflags)
- return obj + goFile, cObj, nil
+ return obj + goFile, cObj, gccObj, nil
}
// An actionQueue is a priority queue of actions.
diff --git a/src/cmd/go/clean.go b/src/cmd/go/clean.go
index 16687f72f..16054a5b5 100644
--- a/src/cmd/go/clean.go
+++ b/src/cmd/go/clean.go
@@ -13,7 +13,7 @@ import (
)
var cmdClean = &Command{
- UsageLine: "clean [-i] [-r] [-n] [-x] [packages]",
+ UsageLine: "clean [-i] [-r] [-n] [-x] [build flags] [packages]",
Short: "remove object files",
Long: `
Clean removes object files from package source directories.
@@ -52,23 +52,26 @@ dependencies of the packages named by the import paths.
The -x flag causes clean to print remove commands as it executes them.
+For more about build flags, see 'go help build'.
+
For more about specifying packages, see 'go help packages'.
`,
}
var cleanI bool // clean -i flag
-var cleanN bool // clean -n flag
var cleanR bool // clean -r flag
-var cleanX bool // clean -x flag
func init() {
// break init cycle
cmdClean.Run = runClean
cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
- cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
- cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
+ // -n and -x are important enough to be
+ // mentioned explicitly in the docs but they
+ // are part of the build flags.
+
+ addBuildFlags(cmdClean)
}
func runClean(cmd *Command, args []string) {
@@ -153,7 +156,7 @@ func clean(p *Package) {
elem+".test.exe",
)
- // Remove a potental executable for each .go file in the directory that
+ // Remove a potential executable for each .go file in the directory that
// is not part of the directory's package.
for _, dir := range dirs {
name := dir.Name()
@@ -169,7 +172,7 @@ func clean(p *Package) {
}
}
- if cleanN || cleanX {
+ if buildN || buildX {
b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
}
@@ -182,9 +185,9 @@ func clean(p *Package) {
if dir.IsDir() {
// TODO: Remove once Makefiles are forgotten.
if cleanDir[name] {
- if cleanN || cleanX {
+ if buildN || buildX {
b.showcmd(p.Dir, "rm -r %s", name)
- if cleanN {
+ if buildN {
continue
}
}
@@ -195,7 +198,7 @@ func clean(p *Package) {
continue
}
- if cleanN {
+ if buildN {
continue
}
@@ -205,28 +208,14 @@ func clean(p *Package) {
}
if cleanI && p.target != "" {
- if cleanN || cleanX {
+ if buildN || buildX {
b.showcmd("", "rm -f %s", p.target)
}
- if !cleanN {
+ if !buildN {
removeFile(p.target)
}
}
- if cleanI && p.usesSwig() {
- for _, f := range stringList(p.SwigFiles, p.SwigCXXFiles) {
- dir := p.swigDir(&buildContext)
- soname := p.swigSoname(f)
- target := filepath.Join(dir, soname)
- if cleanN || cleanX {
- b.showcmd("", "rm -f %s", target)
- }
- if !cleanN {
- removeFile(target)
- }
- }
- }
-
if cleanR {
for _, p1 := range p.imports {
clean(p1)
diff --git a/src/cmd/go/context.go b/src/cmd/go/context.go
new file mode 100644
index 000000000..68e518259
--- /dev/null
+++ b/src/cmd/go/context.go
@@ -0,0 +1,36 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "go/build"
+)
+
+type Context struct {
+ GOARCH string `json:",omitempty"` // target architecture
+ GOOS string `json:",omitempty"` // target operating system
+ GOROOT string `json:",omitempty"` // Go root
+ GOPATH string `json:",omitempty"` // Go path
+ CgoEnabled bool `json:",omitempty"` // whether cgo can be used
+ UseAllFiles bool `json:",omitempty"` // use files regardless of +build lines, file names
+ Compiler string `json:",omitempty"` // compiler to assume when computing target paths
+ BuildTags []string `json:",omitempty"` // build constraints to match in +build lines
+ ReleaseTags []string `json:",omitempty"` // releases the current release is compatible with
+ InstallSuffix string `json:",omitempty"` // suffix to use in the name of the install dir
+}
+
+func newContext(c *build.Context) *Context {
+ return &Context{
+ GOARCH: c.GOARCH,
+ GOOS: c.GOOS,
+ GOROOT: c.GOROOT,
+ CgoEnabled: c.CgoEnabled,
+ UseAllFiles: c.UseAllFiles,
+ Compiler: c.Compiler,
+ BuildTags: c.BuildTags,
+ ReleaseTags: c.ReleaseTags,
+ InstallSuffix: c.InstallSuffix,
+ }
+}
diff --git a/src/cmd/go/discovery.go b/src/cmd/go/discovery.go
index 75228b52a..b9f427995 100644
--- a/src/cmd/go/discovery.go
+++ b/src/cmd/go/discovery.go
@@ -43,6 +43,9 @@ func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
for {
t, err = d.Token()
if err != nil {
+ if err == io.EOF {
+ err = nil
+ }
return
}
if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go
index ebb2f37fd..9840804ce 100644
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -33,6 +33,7 @@ Use "go help [command]" for more information about a command.
Additional help topics:
c calling between Go and C
+ filetype file types
gopath GOPATH environment variable
importpath import path syntax
packages description of package lists
@@ -46,7 +47,7 @@ Compile packages and dependencies
Usage:
- go build [-o output] [build flags] [packages]
+ go build [-o output] [-i] [build flags] [packages]
Build compiles the packages named by the import paths,
along with their dependencies, but it does not install the results.
@@ -67,7 +68,10 @@ derives from the first file name mentioned, such as f1 for 'go build
f1.go f2.go'; with no files provided ('go build'), the output file
name is the base name of the containing directory.
-The build flags are shared by the build, install, run, and test commands:
+The -i flag installs the packages that are dependencies of the target.
+
+The build flags are shared by the build, clean, get, install, list, run,
+and test commands:
-a
force rebuilding of packages that are already up-to-date.
@@ -104,8 +108,8 @@ The build flags are shared by the build, install, run, and test commands:
arguments to pass on each 5l, 6l, or 8l linker invocation.
-tags 'tag list'
a list of build tags to consider satisfied during the build.
- See the documentation for the go/build package for
- more information about build tags.
+ For more information about build tags, see the description of
+ build constraints in the documentation for the go/build package.
The list flags accept a space-separated list of strings. To embed spaces
in an element in the list, surround it with either single or double quotes.
@@ -122,7 +126,7 @@ Remove object files
Usage:
- go clean [-i] [-r] [-n] [-x] [packages]
+ go clean [-i] [-r] [-n] [-x] [build flags] [packages]
Clean removes object files from package source directories.
The go command builds most objects in a temporary directory,
@@ -160,6 +164,8 @@ dependencies of the packages named by the import paths.
The -x flag causes clean to print remove commands as it executes them.
+For more about build flags, see 'go help build'.
+
For more about specifying packages, see 'go help packages'.
@@ -235,8 +241,7 @@ The -u flag instructs get to use the network to update the named packages
and their dependencies. By default, get uses the network to check out
missing packages but does not use it to look for updates to existing packages.
-Get also accepts all the flags in the 'go build' and 'go install' commands,
-to control the installation. See 'go help build'.
+Get also accepts build flags to control the installation. See 'go help build'.
When checking out or updating a package, get looks for a branch or tag
that matches the locally installed version of Go. The most important
@@ -271,7 +276,7 @@ List packages
Usage:
- go list [-e] [-race] [-f format] [-json] [-tags 'tag list'] [packages]
+ go list [-e] [-f format] [-json] [build flags] [packages]
List lists the packages named by the import paths, one per line.
@@ -283,8 +288,7 @@ The default output shows the package import path:
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
-'{{.ImportPath}}'. One extra template function is available, "join",
-which calls strings.Join. The struct being passed to the template is:
+'{{.ImportPath}}'. The struct being passed to the template is:
type Package struct {
Dir string // directory containing package sources
@@ -303,6 +307,7 @@ which calls strings.Join. The struct being passed to the template is:
IgnoredGoFiles []string // .go sources ignored due to build constraints
CFiles []string // .c source files
CXXFiles []string // .cc, .cxx and .cpp source files
+ MFiles []string // .m source files
HFiles []string // .h, .hh, .hpp and .hxx source files
SFiles []string // .s source files
SwigFiles []string // .swig files
@@ -331,6 +336,26 @@ which calls strings.Join. The struct being passed to the template is:
XTestImports []string // imports from XTestGoFiles
}
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+ type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
+ CgoEnabled bool // whether cgo can be used
+ UseAllFiles bool // use files regardless of +build lines, file names
+ Compiler string // compiler to assume when computing target paths
+ BuildTags []string // build constraints to match in +build lines
+ ReleaseTags []string // releases the current release is compatible with
+ InstallSuffix string // suffix to use in the name of the install dir
+ }
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
The -json flag causes the package data to be printed in JSON format
instead of using the template format.
@@ -344,11 +369,7 @@ printing. Erroneous packages will have a non-empty ImportPath and
a non-nil Error field; other information may or may not be missing
(zeroed).
-The -tags flag specifies a list of build tags, like in the 'go build'
-command.
-
-The -race flag causes the package data to include the dependencies
-required by the race detector.
+For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
@@ -357,11 +378,20 @@ Compile and run Go program
Usage:
- go run [build flags] gofiles... [arguments...]
+ go run [build flags] [-exec xprog] gofiles... [arguments...]
Run compiles and runs the main package comprising the named Go source files.
A Go source file is defined to be a file ending in a literal ".go" suffix.
+By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
+If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
+If the -exec flag is not given, GOOS or GOARCH is different from the system
+default, and a program named go_$GOOS_$GOARCH_exec can be found
+on the current search path, 'go run' invokes the binary using that program,
+for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
+cross-compiled programs when a simulator or other execution method is
+available.
+
For more about build flags, see 'go help build'.
See also: go build.
@@ -408,6 +438,10 @@ In addition to the build flags, the flags handled by 'go test' itself are:
Install packages that are dependencies of the test.
Do not run the test.
+ -exec xprog
+ Run the test binary using xprog. The behavior is the same as
+ in 'go run'. See 'go help run' for details.
+
The test binary also accepts flags that control execution of the test; these
flags are also accessible by 'go test'. See 'go help testflag' for details.
@@ -478,12 +512,49 @@ http://swig.org/. When running go build, any file with a .swig
extension will be passed to SWIG. Any file with a .swigcxx extension
will be passed to SWIG with the -c++ option.
-When either cgo or SWIG is used, go build will pass any .c, .s, or .S
-files to the C compiler, and any .cc, .cpp, .cxx files to the C++
+When either cgo or SWIG is used, go build will pass any .c, .m, .s,
+or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++
compiler. The CC or CXX environment variables may be set to determine
the C or C++ compiler, respectively, to use.
+File types
+
+The go command examines the contents of a restricted set of files
+in each directory. It identifies which files to examine based on
+the extension of the file name. These extensions are:
+
+ .go
+ Go source files.
+ .c, .h
+ C source files.
+ If the package uses cgo, these will be compiled with the
+ OS-native compiler (typically gcc); otherwise they will be
+ compiled with the Go-specific support compiler,
+ 5c, 6c, or 8c, etc. as appropriate.
+ .cc, .cpp, .cxx, .hh, .hpp, .hxx
+ C++ source files. Only useful with cgo or SWIG, and always
+ compiled with the OS-native compiler.
+ .m
+ Objective-C source files. Only useful with cgo, and always
+ compiled with the OS-native compiler.
+ .s, .S
+ Assembler source files.
+ If the package uses cgo, these will be assembled with the
+ OS-native assembler (typically gcc (sic)); otherwise they
+ will be assembled with the Go-specific support assembler,
+ 5a, 6a, or 8a, etc., as appropriate.
+ .swig, .swigcxx
+ SWIG definition files.
+ .syso
+ System object files.
+
+Files of each of these types except .syso may contain build
+constraints, but the go command stops scanning for build constraints
+at the first item in the file that is not a blank line or //-style
+line comment.
+
+
GOPATH environment variable
The Go path is used to resolve import statements.
@@ -638,7 +709,7 @@ example.org/user/foo or foo.hg, and
import "example.org/repo.git/foo/bar"
denotes the foo/bar directory of the Git repository at
-example.com/repo or repo.git.
+example.org/repo or repo.git.
When a version control system supports multiple protocols,
each is tried in turn when downloading. For example, a Git
@@ -788,7 +859,8 @@ control the execution of any test:
-covermode set,count,atomic
Set the mode for coverage analysis for the package[s]
- being tested. The default is "set".
+ being tested. The default is "set" unless -race is enabled,
+ in which case it is "atomic".
The values:
set: bool: does this statement run?
count: int: how many times does this statement run?
@@ -823,9 +895,7 @@ control the execution of any test:
Enable more precise (and expensive) memory profiles by setting
runtime.MemProfileRate. See 'godoc runtime MemProfileRate'.
To profile all memory allocations, use -test.memprofilerate=1
- and set the environment variable GOGC=off to disable the
- garbage collector, provided the test can run in the available
- memory without garbage collection.
+ and pass --alloc_space flag to the pprof tool.
-outputdir directory
Place output files from profiling in the specified directory,
diff --git a/src/cmd/go/env.go b/src/cmd/go/env.go
index 2db821797..26d37df4f 100644
--- a/src/cmd/go/env.go
+++ b/src/cmd/go/env.go
@@ -85,18 +85,28 @@ func runEnv(cmd *Command, args []string) {
return
}
- switch runtime.GOOS {
- default:
- for _, e := range env {
- fmt.Printf("%s=\"%s\"\n", e.name, e.value)
- }
- case "plan9":
- for _, e := range env {
- fmt.Printf("%s='%s'\n", e.name, strings.Replace(e.value, "'", "''", -1))
- }
- case "windows":
- for _, e := range env {
- fmt.Printf("set %s=%s\n", e.name, e.value)
+ for _, e := range env {
+ if e.name != "TERM" {
+ switch runtime.GOOS {
+ default:
+ fmt.Printf("%s=\"%s\"\n", e.name, e.value)
+ case "plan9":
+ if strings.IndexByte(e.value, '\x00') < 0 {
+ fmt.Printf("%s='%s'\n", e.name, strings.Replace(e.value, "'", "''", -1))
+ } else {
+ v := strings.Split(e.value, "\x00")
+ fmt.Printf("%s=(", e.name)
+ for x, s := range v {
+ if x > 0 {
+ fmt.Printf(" ")
+ }
+ fmt.Printf("%s", s)
+ }
+ fmt.Printf(")\n")
+ }
+ case "windows":
+ fmt.Printf("set %s=%s\n", e.name, e.value)
+ }
}
}
}
diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go
index e61da7e2a..e708fcf77 100644
--- a/src/cmd/go/get.go
+++ b/src/cmd/go/get.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// TODO: Dashboard upload
-
package main
import (
@@ -37,8 +35,7 @@ The -u flag instructs get to use the network to update the named packages
and their dependencies. By default, get uses the network to check out
missing packages but does not use it to look for updates to existing packages.
-Get also accepts all the flags in the 'go build' and 'go install' commands,
-to control the installation. See 'go help build'.
+Get also accepts build flags to control the installation. See 'go help build'.
When checking out or updating a package, get looks for a branch or tag
that matches the locally installed version of Go. The most important
@@ -73,7 +70,7 @@ func runGet(cmd *Command, args []string) {
}
exitIfErrors()
- // Phase 2. Rescan packages and reevaluate args list.
+ // Phase 2. Rescan packages and re-evaluate args list.
// Code we downloaded and all code that depends on it
// needs to be evicted from the package cache so that
@@ -143,6 +140,10 @@ var downloadRootCache = map[string]bool{}
// for the package named by the argument.
func download(arg string, stk *importStack, getTestDeps bool) {
p := loadPackage(arg, stk)
+ if p.Error != nil && p.Error.hard {
+ errorf("%s", p.Error)
+ return
+ }
// There's nothing to do if this is a package in the standard library.
if p.Standard {
diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
index 71e55175a..40da7e1f5 100644
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -19,8 +19,8 @@ http://swig.org/. When running go build, any file with a .swig
extension will be passed to SWIG. Any file with a .swigcxx extension
will be passed to SWIG with the -c++ option.
-When either cgo or SWIG is used, go build will pass any .c, .s, or .S
-files to the C compiler, and any .cc, .cpp, .cxx files to the C++
+When either cgo or SWIG is used, go build will pass any .c, .m, .s,
+or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++
compiler. The CC or CXX environment variables may be set to determine
the C or C++ compiler, respectively, to use.
`,
@@ -182,7 +182,7 @@ example.org/user/foo or foo.hg, and
import "example.org/repo.git/foo/bar"
denotes the foo/bar directory of the Git repository at
-example.com/repo or repo.git.
+example.org/repo or repo.git.
When a version control system supports multiple protocols,
each is tried in turn when downloading. For example, a Git
@@ -295,3 +295,43 @@ but new packages are always downloaded into the first directory
in the list.
`,
}
+
+var helpFileType = &Command{
+ UsageLine: "filetype",
+ Short: "file types",
+ Long: `
+The go command examines the contents of a restricted set of files
+in each directory. It identifies which files to examine based on
+the extension of the file name. These extensions are:
+
+ .go
+ Go source files.
+ .c, .h
+ C source files.
+ If the package uses cgo, these will be compiled with the
+ OS-native compiler (typically gcc); otherwise they will be
+ compiled with the Go-specific support compiler,
+ 5c, 6c, or 8c, etc. as appropriate.
+ .cc, .cpp, .cxx, .hh, .hpp, .hxx
+ C++ source files. Only useful with cgo or SWIG, and always
+ compiled with the OS-native compiler.
+ .m
+ Objective-C source files. Only useful with cgo, and always
+ compiled with the OS-native compiler.
+ .s, .S
+ Assembler source files.
+ If the package uses cgo, these will be assembled with the
+ OS-native assembler (typically gcc (sic)); otherwise they
+ will be assembled with the Go-specific support assembler,
+ 5a, 6a, or 8a, etc., as appropriate.
+ .swig, .swigcxx
+ SWIG definition files.
+ .syso
+ System object files.
+
+Files of each of these types except .syso may contain build
+constraints, but the go command stops scanning for build constraints
+at the first item in the file that is not a blank line or //-style
+line comment.
+ `,
+}
diff --git a/src/cmd/go/list.go b/src/cmd/go/list.go
index f56ebed38..0ead43502 100644
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -14,7 +14,7 @@ import (
)
var cmdList = &Command{
- UsageLine: "list [-e] [-race] [-f format] [-json] [-tags 'tag list'] [packages]",
+ UsageLine: "list [-e] [-f format] [-json] [build flags] [packages]",
Short: "list packages",
Long: `
List lists the packages named by the import paths, one per line.
@@ -27,8 +27,7 @@ The default output shows the package import path:
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
-'{{.ImportPath}}'. One extra template function is available, "join",
-which calls strings.Join. The struct being passed to the template is:
+'{{.ImportPath}}'. The struct being passed to the template is:
type Package struct {
Dir string // directory containing package sources
@@ -47,6 +46,7 @@ which calls strings.Join. The struct being passed to the template is:
IgnoredGoFiles []string // .go sources ignored due to build constraints
CFiles []string // .c source files
CXXFiles []string // .cc, .cxx and .cpp source files
+ MFiles []string // .m source files
HFiles []string // .h, .hh, .hpp and .hxx source files
SFiles []string // .s source files
SwigFiles []string // .swig files
@@ -75,6 +75,26 @@ which calls strings.Join. The struct being passed to the template is:
XTestImports []string // imports from XTestGoFiles
}
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+ type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
+ CgoEnabled bool // whether cgo can be used
+ UseAllFiles bool // use files regardless of +build lines, file names
+ Compiler string // compiler to assume when computing target paths
+ BuildTags []string // build constraints to match in +build lines
+ ReleaseTags []string // releases the current release is compatible with
+ InstallSuffix string // suffix to use in the name of the install dir
+ }
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
The -json flag causes the package data to be printed in JSON format
instead of using the template format.
@@ -88,11 +108,7 @@ printing. Erroneous packages will have a non-empty ImportPath and
a non-nil Error field; other information may or may not be missing
(zeroed).
-The -tags flag specifies a list of build tags, like in the 'go build'
-command.
-
-The -race flag causes the package data to include the dependencies
-required by the race detector.
+For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
`,
@@ -100,24 +116,18 @@ For more about specifying packages, see 'go help packages'.
func init() {
cmdList.Run = runList // break init cycle
- cmdList.Flag.Var(buildCompiler{}, "compiler", "")
- cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
+ addBuildFlags(cmdList)
}
var listE = cmdList.Flag.Bool("e", false, "")
var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
var listJson = cmdList.Flag.Bool("json", false, "")
-var listRace = cmdList.Flag.Bool("race", false, "")
var nl = []byte{'\n'}
func runList(cmd *Command, args []string) {
out := newTrackingWriter(os.Stdout)
defer out.w.Flush()
- if *listRace {
- buildRace = true
- }
-
var do func(*Package)
if *listJson {
do = func(p *Package) {
@@ -130,7 +140,18 @@ func runList(cmd *Command, args []string) {
out.Write(nl)
}
} else {
- tmpl, err := template.New("main").Funcs(template.FuncMap{"join": strings.Join}).Parse(*listFmt)
+ var cachedCtxt *Context
+ context := func() *Context {
+ if cachedCtxt == nil {
+ cachedCtxt = newContext(&buildContext)
+ }
+ return cachedCtxt
+ }
+ fm := template.FuncMap{
+ "join": strings.Join,
+ "context": context,
+ }
+ tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)
if err != nil {
fatalf("%s", err)
}
@@ -140,7 +161,7 @@ func runList(cmd *Command, args []string) {
fatalf("%s", err)
}
if out.NeedNL() {
- out.Write([]byte{'\n'})
+ out.Write(nl)
}
}
}
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index df0cf1b3f..5b1194aaa 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -89,6 +89,7 @@ var commands = []*Command{
cmdVet,
helpC,
+ helpFileType,
helpGopath,
helpImportPath,
helpPackages,
@@ -238,6 +239,11 @@ func printUsage(w io.Writer) {
}
func usage() {
+ // special case "go test -h"
+ if len(os.Args) > 1 && os.Args[1] == "test" {
+ help([]string{"testflag"})
+ os.Exit(2)
+ }
printUsage(os.Stderr)
os.Exit(2)
}
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 71f14c74a..d45df265b 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -42,6 +42,7 @@ type Package struct {
IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
CFiles []string `json:",omitempty"` // .c source files
CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files
+ MFiles []string `json:",omitempty"` // .m source files
HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
SFiles []string `json:",omitempty"` // .s source files
SwigFiles []string `json:",omitempty"` // .swig files
@@ -88,6 +89,7 @@ type Package struct {
exeName string // desired name for temporary executable
coverMode string // preprocess Go source files with the coverage tool in this mode
coverVars map[string]*CoverVar // variables created by coverage analysis
+ omitDWARF bool // tell linker not to write DWARF information
}
// CoverVar holds the name of the generated coverage variables targeting the named file.
@@ -113,6 +115,7 @@ func (p *Package) copyBuild(pp *build.Package) {
p.IgnoredGoFiles = pp.IgnoredGoFiles
p.CFiles = pp.CFiles
p.CXXFiles = pp.CXXFiles
+ p.MFiles = pp.MFiles
p.HFiles = pp.HFiles
p.SFiles = pp.SFiles
p.SwigFiles = pp.SwigFiles
@@ -136,12 +139,13 @@ type PackageError struct {
Pos string // position of error
Err string // the error itself
isImportCycle bool // the error is an import cycle
+ hard bool // whether the error is soft or hard; soft errors are ignored in some places
}
func (p *PackageError) Error() string {
// Import cycles deserve special treatment.
if p.isImportCycle {
- return fmt.Sprintf("%s: %s\npackage %s\n", p.Pos, p.Err, strings.Join(p.ImportStack, "\n\timports "))
+ return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports "))
}
if p.Pos != "" {
// Omit import stack. The full path to the file where the error
@@ -304,9 +308,14 @@ const (
// goTools is a map of Go program import path to install target directory.
var goTools = map[string]targetDir{
+ "cmd/addr2line": toTool,
"cmd/api": toTool,
"cmd/cgo": toTool,
"cmd/fix": toTool,
+ "cmd/link": toTool,
+ "cmd/nm": toTool,
+ "cmd/objdump": toTool,
+ "cmd/pack": toTool,
"cmd/yacc": toTool,
"code.google.com/p/go.tools/cmd/cover": toTool,
"code.google.com/p/go.tools/cmd/godoc": toBin,
@@ -454,6 +463,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
p.IgnoredGoFiles,
p.CFiles,
p.CXXFiles,
+ p.MFiles,
p.HFiles,
p.SFiles,
p.SysoFiles,
@@ -551,24 +561,6 @@ func (p *Package) usesCgo() bool {
return len(p.CgoFiles) > 0
}
-// swigSoname returns the name of the shared library we create for a
-// SWIG input file.
-func (p *Package) swigSoname(file string) string {
- return strings.Replace(p.ImportPath, "/", "-", -1) + "-" + strings.Replace(file, ".", "-", -1) + ".so"
-}
-
-// swigDir returns the name of the shared SWIG directory for a
-// package.
-func (p *Package) swigDir(ctxt *build.Context) string {
- dir := p.build.PkgRoot
- if ctxt.Compiler == "gccgo" {
- dir = filepath.Join(dir, "gccgo_"+ctxt.GOOS+"_"+ctxt.GOARCH)
- } else {
- dir = filepath.Join(dir, ctxt.GOOS+"_"+ctxt.GOARCH)
- }
- return filepath.Join(dir, "swig")
-}
-
// packageList returns the list of packages in the dag rooted at roots
// as visited in a depth-first post-order traversal.
func packageList(roots []*Package) []*Package {
@@ -681,7 +673,7 @@ func isStale(p *Package, topRoot map[string]bool) bool {
return false
}
- srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
+ srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
for _, src := range srcs {
if olderThan(filepath.Join(p.Dir, src)) {
return true
@@ -724,6 +716,7 @@ func loadPackage(arg string, stk *importStack) *Package {
Error: &PackageError{
ImportStack: stk.copy(),
Err: fmt.Sprintf("invalid import path: cmd/... is reserved for Go commands"),
+ hard: true,
},
}
return p
diff --git a/src/cmd/go/pkg_test.go b/src/cmd/go/pkg_test.go
new file mode 100644
index 000000000..06b9f0ac6
--- /dev/null
+++ b/src/cmd/go/pkg_test.go
@@ -0,0 +1,73 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+var foldDupTests = []struct {
+ list []string
+ f1, f2 string
+}{
+ {stringList("math/rand", "math/big"), "", ""},
+ {stringList("math", "strings"), "", ""},
+ {stringList("strings"), "", ""},
+ {stringList("strings", "strings"), "strings", "strings"},
+ {stringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"},
+}
+
+func TestFoldDup(t *testing.T) {
+ for _, tt := range foldDupTests {
+ f1, f2 := foldDup(tt.list)
+ if f1 != tt.f1 || f2 != tt.f2 {
+ t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2)
+ }
+ }
+}
+
+var parseMetaGoImportsTests = []struct {
+ in string
+ out []metaImport
+}{
+ {
+ `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">`,
+ []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
+ },
+ {
+ `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+ <meta name="go-import" content="baz/quux git http://github.com/rsc/baz/quux">`,
+ []metaImport{
+ {"foo/bar", "git", "https://github.com/rsc/foo/bar"},
+ {"baz/quux", "git", "http://github.com/rsc/baz/quux"},
+ },
+ },
+ {
+ `<head>
+ <meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+ </head>`,
+ []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
+ },
+ {
+ `<meta name="go-import" content="foo/bar git https://github.com/rsc/foo/bar">
+ <body>`,
+ []metaImport{{"foo/bar", "git", "https://github.com/rsc/foo/bar"}},
+ },
+}
+
+func TestParseMetaGoImports(t *testing.T) {
+ for i, tt := range parseMetaGoImportsTests {
+ out, err := parseMetaGoImports(strings.NewReader(tt.in))
+ if err != nil {
+ t.Errorf("test#%d: %v", i, err)
+ continue
+ }
+ if !reflect.DeepEqual(out, tt.out) {
+ t.Errorf("test#%d:\n\thave %q\n\twant %q", i, out, tt.out)
+ }
+ }
+}
diff --git a/src/cmd/go/run.go b/src/cmd/go/run.go
index e6dadd229..ef8aa95a3 100644
--- a/src/cmd/go/run.go
+++ b/src/cmd/go/run.go
@@ -8,16 +8,43 @@ import (
"fmt"
"os"
"os/exec"
+ "runtime"
"strings"
)
+var execCmd []string // -exec flag, for run and test
+
+func findExecCmd() []string {
+ if execCmd != nil {
+ return execCmd
+ }
+ execCmd = []string{} // avoid work the second time
+ if goos == runtime.GOOS && goarch == runtime.GOARCH {
+ return execCmd
+ }
+ path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch))
+ if err == nil {
+ execCmd = []string{path}
+ }
+ return execCmd
+}
+
var cmdRun = &Command{
- UsageLine: "run [build flags] gofiles... [arguments...]",
+ UsageLine: "run [build flags] [-exec xprog] gofiles... [arguments...]",
Short: "compile and run Go program",
Long: `
Run compiles and runs the main package comprising the named Go source files.
A Go source file is defined to be a file ending in a literal ".go" suffix.
+By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
+If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
+If the -exec flag is not given, GOOS or GOARCH is different from the system
+default, and a program named go_$GOOS_$GOARCH_exec can be found
+on the current search path, 'go run' invokes the binary using that program,
+for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
+cross-compiled programs when a simulator or other execution method is
+available.
+
For more about build flags, see 'go help build'.
See also: go build.
@@ -28,6 +55,7 @@ func init() {
cmdRun.Run = runRun // break init loop
addBuildFlags(cmdRun)
+ cmdRun.Flag.Var((*stringsFlag)(&execCmd), "exec", "")
}
func printStderr(args ...interface{}) (int, error) {
@@ -58,6 +86,7 @@ func runRun(cmd *Command, args []string) {
if p.Error != nil {
fatalf("%s", p.Error)
}
+ p.omitDWARF = true
for _, err := range p.DepsErrors {
errorf("%s", err)
}
@@ -89,20 +118,20 @@ func runRun(cmd *Command, args []string) {
// runProgram is the action for running a binary that has already
// been compiled. We ignore exit status.
func (b *builder) runProgram(a *action) error {
+ cmdline := stringList(findExecCmd(), a.deps[0].target, a.args)
if buildN || buildX {
- b.showcmd("", "%s %s", a.deps[0].target, strings.Join(a.args, " "))
+ b.showcmd("", "%s", strings.Join(cmdline, " "))
if buildN {
return nil
}
}
- runStdin(a.deps[0].target, a.args)
+ runStdin(cmdline)
return nil
}
// runStdin is like run, but connects Stdin.
-func runStdin(cmdargs ...interface{}) {
- cmdline := stringList(cmdargs...)
+func runStdin(cmdline []string) {
cmd := exec.Command(cmdline[0], cmdline[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
diff --git a/src/cmd/go/signal_unix.go b/src/cmd/go/signal_unix.go
index 00c71657f..e86cd4652 100644
--- a/src/cmd/go/signal_unix.go
+++ b/src/cmd/go/signal_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package main
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
index f71d67818..0060ce218 100755
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -36,8 +36,9 @@ stop() {
ok=true
allok=true
-unset GOPATH
unset GOBIN
+unset GOPATH
+unset GOROOT
TEST 'file:line in error messages'
# Test that error messages have file:line information at beginning of
@@ -258,6 +259,7 @@ if [ ! -x $d/gobin/godoc ]; then
fi
TEST godoc installs into GOROOT
+GOROOT=$(./testgo env GOROOT)
rm -f $GOROOT/bin/godoc
./testgo install code.google.com/p/go.tools/cmd/godoc
if [ ! -x $GOROOT/bin/godoc ]; then
@@ -425,10 +427,10 @@ d=$(TMPDIR=$tmp mktemp -d -t testgoXXX)
mkdir -p $d/src
(
ln -s $d $d/src/dir1
- cd $d/src/dir1
- echo package p >p.go
+ cd $d/src
+ echo package p >dir1/p.go
export GOPATH=$d
- if [ "$($old/testgo list -f '{{.Root}}' .)" != "$d" ]; then
+ if [ "$($old/testgo list -f '{{.Root}}' dir1)" != "$d" ]; then
echo Confused by symlinks.
echo "Package in current directory $(pwd) should have Root $d"
env|grep WD
@@ -477,14 +479,20 @@ rm -rf $d
TEST case collisions '(issue 4773)'
d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
export GOPATH=$d
-mkdir -p $d/src/example/a $d/src/example/b
+mkdir -p $d/src/example/{a/pkg,a/Pkg,b}
cat >$d/src/example/a/a.go <<EOF
package p
import (
- _ "math/rand"
- _ "math/Rand"
+ _ "example/a/pkg"
+ _ "example/a/Pkg"
)
EOF
+cat >$d/src/example/a/pkg/pkg.go <<EOF
+package pkg
+EOF
+cat >$d/src/example/a/Pkg/pkg.go <<EOF
+package pkg
+EOF
if ./testgo list example/a 2>$d/out; then
echo go list example/a should have failed, did not.
ok=false
@@ -545,7 +553,7 @@ fi
# The error for go install should mention the conflicting directory.
err=$(! ./testgo install ./testdata/shadow/root2/src/foo 2>&1)
-if [ "$err" != "go install: no install location for directory $(pwd)/testdata/shadow/root2/src/foo hidden by $(pwd)/testdata/shadow/root1/src/foo" ]; then
+if [ "$err" != "go install: no install location for $(pwd)/testdata/shadow/root2/src/foo: hidden by $(pwd)/testdata/shadow/root1/src/foo" ]; then
echo wrong shadowed install error: "$err"
ok=false
fi
@@ -555,10 +563,59 @@ TEST source file name order preserved
./testgo test testdata/example[12]_test.go || ok=false
# Check that coverage analysis works at all.
-# Don't worry about the exact numbers
+# Don't worry about the exact numbers but require not 0.0%.
+checkcoverage() {
+ if grep '[^0-9]0\.0%' testdata/cover.txt >/dev/null; then
+ echo 'some coverage results are 0.0%'
+ ok=false
+ fi
+ cat testdata/cover.txt
+ rm -f testdata/cover.txt
+}
+
TEST coverage runs
-./testgo test -short -coverpkg=strings strings regexp || ok=false
-./testgo test -short -cover strings math regexp || ok=false
+./testgo test -short -coverpkg=strings strings regexp >testdata/cover.txt 2>&1 || ok=false
+./testgo test -short -cover strings math regexp >>testdata/cover.txt 2>&1 || ok=false
+checkcoverage
+
+# Check that coverage analysis uses set mode.
+TEST coverage uses set mode
+if ./testgo test -short -cover encoding/binary -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
+ if ! grep -q 'mode: set' testdata/cover.out; then
+ ok=false
+ fi
+ checkcoverage
+else
+ ok=false
+fi
+rm -f testdata/cover.out testdata/cover.txt
+
+TEST coverage uses atomic mode for -race.
+if ./testgo test -short -race -cover encoding/binary -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
+ if ! grep -q 'mode: atomic' testdata/cover.out; then
+ ok=false
+ fi
+ checkcoverage
+else
+ ok=false
+fi
+rm -f testdata/cover.out
+
+TEST coverage uses actual setting to override even for -race.
+if ./testgo test -short -race -cover encoding/binary -covermode=count -coverprofile=testdata/cover.out >testdata/cover.txt 2>&1; then
+ if ! grep -q 'mode: count' testdata/cover.out; then
+ ok=false
+ fi
+ checkcoverage
+else
+ ok=false
+fi
+rm -f testdata/cover.out
+
+TEST coverage with cgo
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+./testgo test -short -cover ./testdata/cgocover >testdata/cover.txt 2>&1 || ok=false
+checkcoverage
TEST cgo depends on syscall
rm -rf $GOROOT/pkg/*_race
@@ -600,7 +657,7 @@ export GOPATH=$d
mkdir -p $d/src/origin
echo '
package origin
-// #cgo LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
+// #cgo !darwin LDFLAGS: -Wl,-rpath -Wl,$ORIGIN
// void f(void) {}
import "C"
@@ -620,6 +677,136 @@ if ! ./testgo test -c -test.bench=XXX fmt; then
fi
rm -f fmt.test
+TEST 'Issue 7573: cmd/cgo: undefined reference when linking a C-library using gccgo'
+d=$(mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/cgoref
+ldflags="-L alibpath -lalib"
+echo "
+package main
+// #cgo LDFLAGS: $ldflags
+// void f(void) {}
+import \"C\"
+
+func main() { C.f() }
+" >$d/src/cgoref/cgoref.go
+go_cmds="$(./testgo build -n -compiler gccgo cgoref 2>&1 1>/dev/null)"
+ldflags_count="$(echo "$go_cmds" | egrep -c "^gccgo.*$(echo $ldflags | sed -e 's/-/\\-/g')" || true)"
+if [ "$ldflags_count" -lt 1 ]; then
+ echo "No Go-inline "#cgo LDFLAGS:" (\"$ldflags\") passed to gccgo linking stage."
+ ok=false
+fi
+rm -rf $d
+unset ldflags_count
+unset go_cmds
+unset ldflags
+unset GOPATH
+
+TEST list template can use context function
+if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then
+ echo unable to use context in list template
+ ok=false
+fi
+
+TEST 'Issue 7108: cmd/go: "go test" should fail if package does not build'
+export GOPATH=$(pwd)/testdata
+if ./testgo test notest >/dev/null 2>&1; then
+ echo 'go test notest succeeded, but should fail'
+ ok=false
+fi
+unset GOPATH
+
+TEST 'Issue 6844: cmd/go: go test -a foo does not rebuild regexp'
+if ! ./testgo test -x -a -c testdata/dep_test.go 2>deplist; then
+ echo "go test -x -a -c testdata/dep_test.go failed"
+ ok=false
+elif ! grep -q regexp deplist; then
+ echo "go test -x -a -c testdata/dep_test.go did not rebuild regexp"
+ ok=false
+fi
+rm -f deplist
+rm -f deps.test
+
+TEST list template can use context function
+if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then
+ echo unable to use context in list template
+ ok=false
+fi
+
+TEST build -i installs dependencies
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+mkdir -p $d/src/x/y/foo $d/src/x/y/bar
+echo '
+package foo
+func F() {}
+' >$d/src/x/y/foo/foo.go
+echo '
+package bar
+import "x/y/foo"
+func F() { foo.F() }
+' >$d/src/x/y/bar/bar.go
+if ! ./testgo build -v -i x/y/bar &> $d/err; then
+ echo build -i failed
+ cat $d/err
+ ok=false
+elif ! grep x/y/foo $d/err >/dev/null; then
+ echo first build -i did not build x/y/foo
+ cat $d/err
+ ok=false
+fi
+if ! ./testgo build -v -i x/y/bar &> $d/err; then
+ echo second build -i failed
+ cat $d/err
+ ok=false
+elif grep x/y/foo $d/err >/dev/null; then
+ echo second build -i built x/y/foo
+ cat $d/err
+ ok=false
+fi
+rm -rf $d
+unset GOPATH
+
+TEST 'go build in test-only directory fails with a good error'
+if ./testgo build ./testdata/testonly 2>testdata/err.out; then
+ echo "go build ./testdata/testonly succeeded, should have failed"
+ ok=false
+elif ! grep 'no buildable Go' testdata/err.out >/dev/null; then
+ echo "go build ./testdata/testonly produced unexpected error:"
+ cat testdata/err.out
+ ok=false
+fi
+rm -f testdata/err.out
+
+TEST 'go test detects test-only import cycles'
+export GOPATH=$(pwd)/testdata
+if ./testgo test -c testcycle/p3 2>testdata/err.out; then
+ echo "go test testcycle/p3 succeeded, should have failed"
+ ok=false
+elif ! grep 'import cycle not allowed in test' testdata/err.out >/dev/null; then
+ echo "go test testcycle/p3 produced unexpected error:"
+ cat testdata/err.out
+ ok=false
+fi
+rm -f testdata/err.out
+unset GOPATH
+
+TEST 'go test foo_test.go works'
+if ! ./testgo test testdata/standalone_test.go; then
+ echo "go test testdata/standalone_test.go failed"
+ ok=false
+fi
+
+TEST 'go test xtestonly works'
+export GOPATH=$(pwd)/testdata
+./testgo clean -i xtestonly
+if ! ./testgo test xtestonly >/dev/null; then
+ echo "go test xtestonly failed"
+ ok=false
+fi
+unset GOPATH
+
+
# clean up
if $started; then stop; fi
rm -rf testdata/bin testdata/bin1
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index 06ac9d206..5935c98db 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -72,6 +72,10 @@ In addition to the build flags, the flags handled by 'go test' itself are:
Install packages that are dependencies of the test.
Do not run the test.
+ -exec xprog
+ Run the test binary using xprog. The behavior is the same as
+ in 'go run'. See 'go help run' for details.
+
The test binary also accepts flags that control execution of the test; these
flags are also accessible by 'go test'. See 'go help testflag' for details.
@@ -133,7 +137,8 @@ control the execution of any test:
-covermode set,count,atomic
Set the mode for coverage analysis for the package[s]
- being tested. The default is "set".
+ being tested. The default is "set" unless -race is enabled,
+ in which case it is "atomic".
The values:
set: bool: does this statement run?
count: int: how many times does this statement run?
@@ -168,9 +173,7 @@ control the execution of any test:
Enable more precise (and expensive) memory profiles by setting
runtime.MemProfileRate. See 'godoc runtime MemProfileRate'.
To profile all memory allocations, use -test.memprofilerate=1
- and set the environment variable GOGC=off to disable the
- garbage collector, provided the test can run in the available
- memory without garbage collection.
+ and pass --alloc_space flag to the pprof tool.
-outputdir directory
Place output files from profiling in the specified directory,
@@ -273,7 +276,6 @@ var (
testCoverPkgs []*Package // -coverpkg flag
testProfile bool // some profiling flag
testNeedBinary bool // profile needs to keep binary around
- testI bool // -i flag
testV bool // -v flag
testFiles []string // -file flag(s) TODO: not respected
testTimeout string // -timeout flag
@@ -295,6 +297,8 @@ func runTest(cmd *Command, args []string) {
var pkgArgs []string
pkgArgs, testArgs = testFlags(args)
+ findExecCmd() // initialize cached result
+
raceInit()
pkgs := packagesForBuild(pkgArgs)
if len(pkgs) == 0 {
@@ -334,7 +338,7 @@ func runTest(cmd *Command, args []string) {
var b builder
b.init()
- if testI {
+ if buildI {
buildV = testV
deps := make(map[string]bool)
@@ -411,7 +415,11 @@ func runTest(cmd *Command, args []string) {
p.Stale = true // rebuild
p.fake = true // do not warn about rebuild
p.coverMode = testCoverMode
- p.coverVars = declareCoverVars(p.ImportPath, p.GoFiles...)
+ var coverFiles []string
+ coverFiles = append(coverFiles, p.GoFiles...)
+ coverFiles = append(coverFiles, p.CgoFiles...)
+ coverFiles = append(coverFiles, p.TestGoFiles...)
+ p.coverVars = declareCoverVars(p.ImportPath, coverFiles...)
}
}
@@ -516,7 +524,7 @@ func contains(x []string, s string) bool {
func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, err error) {
if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
- build := &action{p: p}
+ build := b.action(modeBuild, modeBuild, p)
run := &action{p: p, deps: []*action{build}}
print := &action{f: (*builder).notest, p: p, deps: []*action{run}}
return build, run, print, nil
@@ -530,16 +538,31 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
var imports, ximports []*Package
var stk importStack
- stk.push(p.ImportPath + "_test")
+ stk.push(p.ImportPath + " (test)")
for _, path := range p.TestImports {
p1 := loadImport(path, p.Dir, &stk, p.build.TestImportPos[path])
if p1.Error != nil {
return nil, nil, nil, p1.Error
}
+ if contains(p1.Deps, p.ImportPath) {
+ // Same error that loadPackage returns (via reusePackage) in pkg.go.
+ // Can't change that code, because that code is only for loading the
+ // non-test copy of a package.
+ err := &PackageError{
+ ImportStack: testImportStack(stk[0], p1, p.ImportPath),
+ Err: "import cycle not allowed in test",
+ isImportCycle: true,
+ }
+ return nil, nil, nil, err
+ }
imports = append(imports, p1)
}
+ stk.pop()
+ stk.push(p.ImportPath + "_test")
+ pxtestNeedsPtest := false
for _, path := range p.XTestImports {
if path == p.ImportPath {
+ pxtestNeedsPtest = true
continue
}
p1 := loadImport(path, p.Dir, &stk, p.build.XTestImportPos[path])
@@ -618,7 +641,10 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
if localCover {
ptest.coverMode = testCoverMode
- ptest.coverVars = declareCoverVars(ptest.ImportPath, ptest.GoFiles...)
+ var coverFiles []string
+ coverFiles = append(coverFiles, ptest.GoFiles...)
+ coverFiles = append(coverFiles, ptest.CgoFiles...)
+ ptest.coverVars = declareCoverVars(ptest.ImportPath, coverFiles...)
}
} else {
ptest = p
@@ -637,11 +663,14 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
build: &build.Package{
ImportPos: p.build.XTestImportPos,
},
- imports: append(ximports, ptest),
+ imports: ximports,
pkgdir: testDir,
fake: true,
Stale: true,
}
+ if pxtestNeedsPtest {
+ pxtest.imports = append(pxtest.imports, ptest)
+ }
}
// Action for building pkg.test.
@@ -651,21 +680,20 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
GoFiles: []string{"_testmain.go"},
ImportPath: "testmain",
Root: p.Root,
- imports: []*Package{ptest},
build: &build.Package{Name: "main"},
pkgdir: testDir,
fake: true,
Stale: true,
- }
- if pxtest != nil {
- pmain.imports = append(pmain.imports, pxtest)
+ omitDWARF: !testC && !testNeedBinary,
}
// The generated main also imports testing and regexp.
stk.push("testmain")
for dep := range testMainDeps {
- if ptest.ImportPath != dep {
- p1 := loadImport("testing", "", &stk, nil)
+ if dep == ptest.ImportPath {
+ pmain.imports = append(pmain.imports, ptest)
+ } else {
+ p1 := loadImport(dep, "", &stk, nil)
if p1.Error != nil {
return nil, nil, nil, p1.Error
}
@@ -687,6 +715,21 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
}
}
+ // Do initial scan for metadata needed for writing _testmain.go
+ // Use that metadata to update the list of imports for package main.
+ // The list of imports is used by recompileForTest and by the loop
+ // afterward that gathers t.Cover information.
+ t, err := loadTestFuncs(ptest)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ if t.NeedTest || ptest.coverMode != "" {
+ pmain.imports = append(pmain.imports, ptest)
+ }
+ if t.NeedXtest {
+ pmain.imports = append(pmain.imports, pxtest)
+ }
+
if ptest != p && localCover {
// We have made modifications to the package p being tested
// and are rebuilding p (as ptest), writing it to the testDir tree.
@@ -703,7 +746,15 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
recompileForTest(pmain, p, ptest, testDir)
}
- if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), pmain, ptest); err != nil {
+ for _, cp := range pmain.imports {
+ if len(cp.coverVars) > 0 {
+ t.Cover = append(t.Cover, coverInfo{cp, cp.coverVars})
+ }
+ }
+
+ // writeTestmain writes _testmain.go. This must happen after recompileForTest,
+ // because recompileForTest modifies XXX.
+ if err := writeTestmain(filepath.Join(testDir, "_testmain.go"), t); err != nil {
return nil, nil, nil, err
}
@@ -711,7 +762,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
if ptest != p {
a := b.action(modeBuild, modeBuild, ptest)
- a.objdir = testDir + string(filepath.Separator)
+ a.objdir = testDir + string(filepath.Separator) + "_obj_test" + string(filepath.Separator)
a.objpkg = ptestObj
a.target = ptestObj
a.link = false
@@ -719,7 +770,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
if pxtest != nil {
a := b.action(modeBuild, modeBuild, pxtest)
- a.objdir = testDir + string(filepath.Separator)
+ a.objdir = testDir + string(filepath.Separator) + "_obj_xtest" + string(filepath.Separator)
a.objpkg = buildToolchain.pkgpath(testDir, pxtest)
a.target = a.objpkg
}
@@ -765,6 +816,24 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
return pmainAction, runAction, printAction, nil
}
+func testImportStack(top string, p *Package, target string) []string {
+ stk := []string{top, p.ImportPath}
+Search:
+ for p.ImportPath != target {
+ for _, p1 := range p.imports {
+ if p1.ImportPath == target || contains(p1.Deps, target) {
+ stk = append(stk, p1.ImportPath)
+ p = p1
+ continue Search
+ }
+ }
+ // Can't happen, but in case it does...
+ stk = append(stk, "<lost path to cycle>")
+ break
+ }
+ return stk
+}
+
func recompileForTest(pmain, preal, ptest *Package, testDir string) {
// The "test copy" of preal is ptest.
// For each package that depends on preal, make a "test copy"
@@ -836,7 +905,7 @@ func declareCoverVars(importPath string, files ...string) map[string]*CoverVar {
// runTest is the action for running a test binary.
func (b *builder) runTest(a *action) error {
- args := stringList(a.deps[0].target, testArgs)
+ args := stringList(findExecCmd(), a.deps[0].target, testArgs)
a.testOutput = new(bytes.Buffer)
if buildN || buildX {
@@ -1007,31 +1076,26 @@ type coverInfo struct {
Vars map[string]*CoverVar
}
-// writeTestmain writes the _testmain.go file for package p to
-// the file named out.
-func writeTestmain(out string, pmain, p *Package) error {
- var cover []coverInfo
- for _, cp := range pmain.imports {
- if len(cp.coverVars) > 0 {
- cover = append(cover, coverInfo{cp, cp.coverVars})
- }
- }
-
+// loadTestFuncs returns the testFuncs describing the tests that will be run.
+func loadTestFuncs(ptest *Package) (*testFuncs, error) {
t := &testFuncs{
- Package: p,
- Cover: cover,
+ Package: ptest,
}
- for _, file := range p.TestGoFiles {
- if err := t.load(filepath.Join(p.Dir, file), "_test", &t.NeedTest); err != nil {
- return err
+ for _, file := range ptest.TestGoFiles {
+ if err := t.load(filepath.Join(ptest.Dir, file), "_test", &t.NeedTest); err != nil {
+ return nil, err
}
}
- for _, file := range p.XTestGoFiles {
- if err := t.load(filepath.Join(p.Dir, file), "_xtest", &t.NeedXtest); err != nil {
- return err
+ for _, file := range ptest.XTestGoFiles {
+ if err := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.NeedXtest); err != nil {
+ return nil, err
}
}
+ return t, nil
+}
+// writeTestmain writes the _testmain.go file for t to the file named out.
+func writeTestmain(out string, t *testFuncs) error {
f, err := os.Create(out)
if err != nil {
return err
diff --git a/src/cmd/go/testdata/cgocover/p.go b/src/cmd/go/testdata/cgocover/p.go
new file mode 100644
index 000000000..a6a3891cd
--- /dev/null
+++ b/src/cmd/go/testdata/cgocover/p.go
@@ -0,0 +1,19 @@
+package p
+
+/*
+void
+f(void)
+{
+}
+*/
+import "C"
+
+var b bool
+
+func F() {
+ if b {
+ for {
+ }
+ }
+ C.f()
+}
diff --git a/src/cmd/go/testdata/cgocover/p_test.go b/src/cmd/go/testdata/cgocover/p_test.go
new file mode 100644
index 000000000..a8f057e35
--- /dev/null
+++ b/src/cmd/go/testdata/cgocover/p_test.go
@@ -0,0 +1,7 @@
+package p
+
+import "testing"
+
+func TestF(t *testing.T) {
+ F()
+}
diff --git a/src/cmd/go/testdata/dep_test.go b/src/cmd/go/testdata/dep_test.go
new file mode 100644
index 000000000..0c53ac4f9
--- /dev/null
+++ b/src/cmd/go/testdata/dep_test.go
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package deps
+
+import _ "testing"
diff --git a/src/cmd/go/testdata/src/notest/hello.go b/src/cmd/go/testdata/src/notest/hello.go
new file mode 100644
index 000000000..7c42c32fb
--- /dev/null
+++ b/src/cmd/go/testdata/src/notest/hello.go
@@ -0,0 +1,6 @@
+package notest
+
+func hello() {
+ println("hello world")
+}
+Hello world
diff --git a/src/cmd/go/testdata/src/testcycle/p1/p1.go b/src/cmd/go/testdata/src/testcycle/p1/p1.go
new file mode 100644
index 000000000..65ab76d4e
--- /dev/null
+++ b/src/cmd/go/testdata/src/testcycle/p1/p1.go
@@ -0,0 +1,7 @@
+package p1
+
+import _ "testcycle/p2"
+
+func init() {
+ println("p1 init")
+}
diff --git a/src/cmd/go/testdata/src/testcycle/p1/p1_test.go b/src/cmd/go/testdata/src/testcycle/p1/p1_test.go
new file mode 100644
index 000000000..75abb13e6
--- /dev/null
+++ b/src/cmd/go/testdata/src/testcycle/p1/p1_test.go
@@ -0,0 +1,6 @@
+package p1
+
+import "testing"
+
+func Test(t *testing.T) {
+}
diff --git a/src/cmd/go/testdata/src/testcycle/p2/p2.go b/src/cmd/go/testdata/src/testcycle/p2/p2.go
new file mode 100644
index 000000000..7e26cdf19
--- /dev/null
+++ b/src/cmd/go/testdata/src/testcycle/p2/p2.go
@@ -0,0 +1,7 @@
+package p2
+
+import _ "testcycle/p3"
+
+func init() {
+ println("p2 init")
+}
diff --git a/src/cmd/go/testdata/src/testcycle/p3/p3.go b/src/cmd/go/testdata/src/testcycle/p3/p3.go
new file mode 100644
index 000000000..bb0a2f4f6
--- /dev/null
+++ b/src/cmd/go/testdata/src/testcycle/p3/p3.go
@@ -0,0 +1,5 @@
+package p3
+
+func init() {
+ println("p3 init")
+}
diff --git a/src/cmd/go/testdata/src/testcycle/p3/p3_test.go b/src/cmd/go/testdata/src/testcycle/p3/p3_test.go
new file mode 100644
index 000000000..9b4b0757f
--- /dev/null
+++ b/src/cmd/go/testdata/src/testcycle/p3/p3_test.go
@@ -0,0 +1,10 @@
+package p3
+
+import (
+ "testing"
+
+ _ "testcycle/p1"
+)
+
+func Test(t *testing.T) {
+}
diff --git a/src/cmd/go/testdata/src/xtestonly/f.go b/src/cmd/go/testdata/src/xtestonly/f.go
new file mode 100644
index 000000000..dac039e1a
--- /dev/null
+++ b/src/cmd/go/testdata/src/xtestonly/f.go
@@ -0,0 +1,3 @@
+package xtestonly
+
+func F() int { return 42 }
diff --git a/src/cmd/go/testdata/src/xtestonly/f_test.go b/src/cmd/go/testdata/src/xtestonly/f_test.go
new file mode 100644
index 000000000..01f6e8373
--- /dev/null
+++ b/src/cmd/go/testdata/src/xtestonly/f_test.go
@@ -0,0 +1,12 @@
+package xtestonly_test
+
+import (
+ "testing"
+ "xtestonly"
+)
+
+func TestF(t *testing.T) {
+ if x := xtestonly.F(); x != 42 {
+ t.Errorf("f.F() = %d, want 42", x)
+ }
+}
diff --git a/src/cmd/go/testdata/standalone_test.go b/src/cmd/go/testdata/standalone_test.go
new file mode 100644
index 000000000..59cf918b9
--- /dev/null
+++ b/src/cmd/go/testdata/standalone_test.go
@@ -0,0 +1,6 @@
+package standalone_test
+
+import "testing"
+
+func Test(t *testing.T) {
+}
diff --git a/src/cmd/go/testdata/testonly/p_test.go b/src/cmd/go/testdata/testonly/p_test.go
new file mode 100644
index 000000000..c89cd18d0
--- /dev/null
+++ b/src/cmd/go/testdata/testonly/p_test.go
@@ -0,0 +1 @@
+package p
diff --git a/src/cmd/go/testflag.go b/src/cmd/go/testflag.go
index aea81d8f8..73f311e5f 100644
--- a/src/cmd/go/testflag.go
+++ b/src/cmd/go/testflag.go
@@ -66,7 +66,6 @@ var testFlagDefn = []*testFlagSpec{
// local.
{name: "c", boolVar: &testC},
{name: "file", multiOK: true},
- {name: "i", boolVar: &testI},
{name: "cover", boolVar: &testCover},
{name: "coverpkg"},
@@ -75,8 +74,11 @@ var testFlagDefn = []*testFlagSpec{
{name: "n", boolVar: &buildN},
{name: "p"},
{name: "x", boolVar: &buildX},
+ {name: "i", boolVar: &buildI},
{name: "work", boolVar: &buildWork},
+ {name: "ccflags"},
{name: "gcflags"},
+ {name: "exec"},
{name: "ldflags"},
{name: "gccgoflags"},
{name: "tags"},
@@ -116,7 +118,6 @@ var testFlagDefn = []*testFlagSpec{
func testFlags(args []string) (packageNames, passToTest []string) {
inPkg := false
outputDir := ""
- testCoverMode = "set"
for i := 0; i < len(args); i++ {
if !strings.HasPrefix(args[i], "-") {
if !inPkg && packageNames == nil {
@@ -154,6 +155,16 @@ func testFlags(args []string) (packageNames, passToTest []string) {
setBoolFlag(f.boolVar, value)
case "p":
setIntFlag(&buildP, value)
+ case "exec":
+ execCmd, err = splitQuotedFields(value)
+ if err != nil {
+ fatalf("invalid flag argument for -%s: %v", f.name, err)
+ }
+ case "ccflags":
+ buildCcflags, err = splitQuotedFields(value)
+ if err != nil {
+ fatalf("invalid flag argument for -%s: %v", f.name, err)
+ }
case "gcflags":
buildGcflags, err = splitQuotedFields(value)
if err != nil {
@@ -212,6 +223,14 @@ func testFlags(args []string) (packageNames, passToTest []string) {
}
}
+ if testCoverMode == "" {
+ testCoverMode = "set"
+ if buildRace {
+ // Default coverage mode is atomic when -race is set.
+ testCoverMode = "atomic"
+ }
+ }
+
// Tell the test what directory we're running in, so it can write the profiles there.
if testProfile && outputDir == "" {
dir, err := os.Getwd()
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 22d5ebc24..8f0bae0b7 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -354,6 +354,8 @@ type repoRoot struct {
root string
}
+var httpPrefixRE = regexp.MustCompile(`^https?:`)
+
// repoRootForImportPath analyzes importPath to determine the
// version control system, and code repository to use.
func repoRootForImportPath(importPath string) (*repoRoot, error) {
@@ -390,8 +392,12 @@ var errUnknownSite = errors.New("dynamic lookup required to find mapping")
//
// If scheme is non-empty, that scheme is forced.
func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
- if strings.Contains(importPath, "://") {
- return nil, fmt.Errorf("invalid import path %q", importPath)
+ // A common error is to use https://packagepath because that's what
+ // hg and git require. Diagnose this helpfully.
+ if loc := httpPrefixRE.FindStringIndex(importPath); loc != nil {
+ // The importPath has been cleaned, so has only one slash. The pattern
+ // ignores the slashes; the error message puts them back on the RHS at least.
+ return nil, fmt.Errorf("%q not allowed in import path", importPath[loc[0]:loc[1]]+"//")
}
for _, srv := range vcsPaths {
if !strings.HasPrefix(importPath, srv.prefix) {
diff --git a/src/cmd/gofmt/doc.go b/src/cmd/gofmt/doc.go
index 94e67fd89..8f73ef5b9 100644
--- a/src/cmd/gofmt/doc.go
+++ b/src/cmd/gofmt/doc.go
@@ -4,6 +4,7 @@
/*
Gofmt formats Go programs.
+It uses tabs (width = 8) for indentation and blanks for alignment.
Without an explicit path, it processes the standard input. Given a file,
it operates on that file; given a directory, it operates on all .go files in
@@ -33,13 +34,9 @@ The flags are:
If a file's formatting is different from gofmt's, overwrite it
with gofmt's version.
-Formatting control flags:
- -comments=true
- Print comments; if false, all comments are elided from the output.
- -tabs=true
- Indent with tabs; if false, spaces are used instead.
- -tabwidth=8
- Tab width in spaces.
+Debugging support:
+ -cpuprofile filename
+ Write cpu profile to the specified file.
The rewrite rule specified with the -r flag must be a string of the form:
diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go
index 861ff9390..576cae522 100644
--- a/src/cmd/gofmt/gofmt.go
+++ b/src/cmd/gofmt/gofmt.go
@@ -31,21 +31,20 @@ var (
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
allErrors = flag.Bool("e", false, "report all errors (not just the first 10 on different lines)")
- // layout control
- comments = flag.Bool("comments", true, "print comments")
- tabWidth = flag.Int("tabwidth", 8, "tab width")
- tabIndent = flag.Bool("tabs", true, "indent with tabs")
-
// debugging
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file")
)
+const (
+ tabWidth = 8
+ printerMode = printer.UseSpaces | printer.TabIndent
+)
+
var (
- fileSet = token.NewFileSet() // per process FileSet
- exitCode = 0
- rewrite func(*ast.File) *ast.File
- parserMode parser.Mode
- printerMode printer.Mode
+ fileSet = token.NewFileSet() // per process FileSet
+ exitCode = 0
+ rewrite func(*ast.File) *ast.File
+ parserMode parser.Mode
)
func report(err error) {
@@ -60,22 +59,12 @@ func usage() {
}
func initParserMode() {
- parserMode = parser.Mode(0)
- if *comments {
- parserMode |= parser.ParseComments
- }
+ parserMode = parser.ParseComments
if *allErrors {
parserMode |= parser.AllErrors
}
}
-func initPrinterMode() {
- printerMode = printer.UseSpaces
- if *tabIndent {
- printerMode |= printer.TabIndent
- }
-}
-
func isGoFile(f os.FileInfo) bool {
// ignore non-Go files
name := f.Name()
@@ -118,7 +107,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
}
var buf bytes.Buffer
- err = (&printer.Config{Mode: printerMode, Tabwidth: *tabWidth}).Fprint(&buf, fileSet, file)
+ err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(&buf, fileSet, file)
if err != nil {
return err
}
@@ -180,11 +169,6 @@ func main() {
func gofmtMain() {
flag.Usage = usage
flag.Parse()
- if *tabWidth < 0 {
- fmt.Fprintf(os.Stderr, "negative tabwidth %d\n", *tabWidth)
- exitCode = 2
- return
- }
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
@@ -199,7 +183,6 @@ func gofmtMain() {
}
initParserMode()
- initPrinterMode()
initRewrite()
if flag.NArg() == 0 {
diff --git a/src/cmd/gofmt/gofmt_test.go b/src/cmd/gofmt/gofmt_test.go
index 75a322a6c..b9335b8f3 100644
--- a/src/cmd/gofmt/gofmt_test.go
+++ b/src/cmd/gofmt/gofmt_test.go
@@ -40,7 +40,6 @@ func runTest(t *testing.T, in, out, flags string) {
}
initParserMode()
- initPrinterMode()
initRewrite()
var buf bytes.Buffer
diff --git a/src/cmd/gofmt/long_test.go b/src/cmd/gofmt/long_test.go
index 862e9d987..108278b33 100644
--- a/src/cmd/gofmt/long_test.go
+++ b/src/cmd/gofmt/long_test.go
@@ -38,7 +38,7 @@ func gofmt(fset *token.FileSet, filename string, src *bytes.Buffer) error {
}
ast.SortImports(fset, f)
src.Reset()
- return (&printer.Config{Mode: printerMode, Tabwidth: *tabWidth}).Fprint(src, fset, f)
+ return (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(src, fset, f)
}
func testFile(t *testing.T, b1, b2 *bytes.Buffer, filename string) {
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index 66d2331a5..fb6c6fc81 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -48,7 +48,7 @@ func parseExpr(s, what string) ast.Expr {
/*
func dump(msg string, val reflect.Value) {
fmt.Printf("%s:\n", msg)
- ast.Print(fset, val.Interface())
+ ast.Print(fileSet, val.Interface())
fmt.Println()
}
*/
@@ -59,8 +59,9 @@ func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
m := make(map[string]reflect.Value)
pat := reflect.ValueOf(pattern)
repl := reflect.ValueOf(replace)
- var f func(val reflect.Value) reflect.Value // f is recursive
- f = func(val reflect.Value) reflect.Value {
+
+ var rewriteVal func(val reflect.Value) reflect.Value
+ rewriteVal = func(val reflect.Value) reflect.Value {
// don't bother if val is invalid to start with
if !val.IsValid() {
return reflect.Value{}
@@ -68,22 +69,22 @@ func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
for k := range m {
delete(m, k)
}
- val = apply(f, val)
+ val = apply(rewriteVal, val)
if match(m, pat, val) {
val = subst(m, repl, reflect.ValueOf(val.Interface().(ast.Node).Pos()))
}
return val
}
- r := apply(f, reflect.ValueOf(p)).Interface().(*ast.File)
+
+ r := apply(rewriteVal, reflect.ValueOf(p)).Interface().(*ast.File)
r.Comments = cmap.Filter(r).Comments() // recreate comments list
return r
}
-// setValue is a wrapper for x.SetValue(y); it protects
-// the caller from panics if x cannot be changed to y.
-func setValue(x, y reflect.Value) {
- // don't bother if y is invalid to start with
- if !y.IsValid() {
+// set is a wrapper for x.Set(y); it protects the caller from panics if x cannot be changed to y.
+func set(x, y reflect.Value) {
+ // don't bother if x cannot be set or y is invalid
+ if !x.CanSet() || !y.IsValid() {
return
}
defer func() {
@@ -134,16 +135,16 @@ func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value
case reflect.Slice:
for i := 0; i < v.Len(); i++ {
e := v.Index(i)
- setValue(e, f(e))
+ set(e, f(e))
}
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
e := v.Field(i)
- setValue(e, f(e))
+ set(e, f(e))
}
case reflect.Interface:
e := v.Elem()
- setValue(v, f(e))
+ set(v, f(e))
}
return val
}
diff --git a/src/cmd/gofmt/testdata/typeswitch.golden b/src/cmd/gofmt/testdata/typeswitch.golden
index 87e916181..2b1905edd 100644
--- a/src/cmd/gofmt/testdata/typeswitch.golden
+++ b/src/cmd/gofmt/testdata/typeswitch.golden
@@ -4,7 +4,7 @@
into the correct unparenthesized form.
Only type-switches that didn't declare a variable
- in the the type switch type assertion and which
+ in the type switch type assertion and which
contained only "expression-like" (named) types in their
cases were permitted to have their type assertion parenthesized
by go/parser (due to a weak predicate in the parser). All others
diff --git a/src/cmd/gofmt/testdata/typeswitch.input b/src/cmd/gofmt/testdata/typeswitch.input
index f90f28949..8f8cba9b8 100644
--- a/src/cmd/gofmt/testdata/typeswitch.input
+++ b/src/cmd/gofmt/testdata/typeswitch.input
@@ -4,7 +4,7 @@
into the correct unparenthesized form.
Only type-switches that didn't declare a variable
- in the the type switch type assertion and which
+ in the type switch type assertion and which
contained only "expression-like" (named) types in their
cases were permitted to have their type assertion parenthesized
by go/parser (due to a weak predicate in the parser). All others
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 30d7c8185..55d020710 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -38,15 +38,14 @@
#include "../../pkg/runtime/mgc0.h"
void dynreloc(void);
-static vlong addaddrplus4(Sym *s, Sym *t, vlong add);
/*
* divide-and-conquer list-link
- * sort of Sym* structures.
+ * sort of LSym* structures.
* Used for the data block.
*/
int
-datcmp(Sym *s1, Sym *s2)
+datcmp(LSym *s1, LSym *s2)
{
if(s1->type != s2->type)
return (int)s1->type - (int)s2->type;
@@ -58,11 +57,11 @@ datcmp(Sym *s1, Sym *s2)
return strcmp(s1->name, s2->name);
}
-Sym*
-listsort(Sym *l, int (*cmp)(Sym*, Sym*), int off)
+LSym*
+listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off)
{
- Sym *l1, *l2, *le;
- #define NEXT(l) (*(Sym**)((char*)(l)+off))
+ LSym *l1, *l2, *le;
+ #define NEXT(l) (*(LSym**)((char*)(l)+off))
if(l == 0 || NEXT(l) == 0)
return l;
@@ -128,32 +127,16 @@ listsort(Sym *l, int (*cmp)(Sym*, Sym*), int off)
#undef NEXT
}
-Reloc*
-addrel(Sym *s)
-{
- if(s->nr >= s->maxr) {
- if(s->maxr == 0)
- s->maxr = 4;
- else
- s->maxr <<= 1;
- s->r = erealloc(s->r, s->maxr*sizeof s->r[0]);
- memset(s->r+s->nr, 0, (s->maxr-s->nr)*sizeof s->r[0]);
- }
- return &s->r[s->nr++];
-}
-
void
-relocsym(Sym *s)
+relocsym(LSym *s)
{
Reloc *r;
- Sym *rs;
- Prog p;
+ LSym *rs;
int32 i, off, siz, fl;
vlong o;
uchar *cast;
- cursym = s;
- memset(&p, 0, sizeof p);
+ ctxt->cursym = s;
for(r=s->r; r<s->r+s->nr; r++) {
r->done = 1;
off = r->off;
@@ -168,10 +151,12 @@ relocsym(Sym *s)
}
if(r->type >= 256)
continue;
+ if(r->siz == 0) // informational relocation - no work to do
+ continue;
- if(r->sym != S && r->sym->type == SDYNIMPORT)
+ // Solaris needs the ability to reference dynimport symbols.
+ if(HEADTYPE != Hsolaris && r->sym != S && r->sym->type == SDYNIMPORT)
diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type);
-
if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable)
diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);
@@ -181,13 +166,56 @@ relocsym(Sym *s)
if(archreloc(r, s, &o) < 0)
diag("unknown reloc %d", r->type);
break;
- case D_TLS:
+ case R_TLS:
+ if(linkmode == LinkInternal && iself && thechar == '5') {
+ // On ELF ARM, the thread pointer is 8 bytes before
+ // the start of the thread-local data block, so add 8
+ // to the actual TLS offset (r->sym->value).
+ // This 8 seems to be a fundamental constant of
+ // ELF on ARM (or maybe Glibc on ARM); it is not
+ // related to the fact that our own TLS storage happens
+ // to take up 8 bytes.
+ o = 8 + r->sym->value;
+ break;
+ }
r->done = 0;
o = 0;
if(thechar != '6')
o = r->add;
break;
- case D_ADDR:
+ case R_TLS_LE:
+ if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) {
+ r->done = 0;
+ r->sym = ctxt->gmsym;
+ r->xsym = ctxt->gmsym;
+ r->xadd = r->add;
+ o = 0;
+ if(thechar != '6')
+ o = r->add;
+ break;
+ }
+ o = ctxt->tlsoffset + r->add;
+ break;
+
+ case R_TLS_IE:
+ if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) {
+ r->done = 0;
+ r->sym = ctxt->gmsym;
+ r->xsym = ctxt->gmsym;
+ r->xadd = r->add;
+ o = 0;
+ if(thechar != '6')
+ o = r->add;
+ break;
+ }
+ if(iself || ctxt->headtype == Hplan9)
+ o = ctxt->tlsoffset + r->add;
+ else if(ctxt->headtype == Hwindows)
+ o = r->add;
+ else
+ sysfatal("unexpected R_TLS_IE relocation for %s", headstr(ctxt->headtype));
+ break;
+ case R_ADDR:
if(linkmode == LinkExternal && r->sym->type != SCONST) {
r->done = 0;
@@ -198,7 +226,7 @@ relocsym(Sym *s)
r->xadd += symaddr(rs) - symaddr(rs->outer);
rs = rs->outer;
}
- if(rs->type != SHOSTOBJ && rs->sect == nil)
+ if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
diag("missing section for %s", rs->name);
r->xsym = rs;
@@ -210,15 +238,26 @@ relocsym(Sym *s)
if(rs->type != SHOSTOBJ)
o += symaddr(rs);
} else {
- diag("unhandled pcrel relocation for %s", headtype);
+ diag("unhandled pcrel relocation for %s", headstring);
}
break;
}
o = symaddr(r->sym) + r->add;
+
+ // On amd64, 4-byte offsets will be sign-extended, so it is impossible to
+ // access more than 2GB of static data; fail at link time is better than
+ // fail at runtime. See http://golang.org/issue/7980.
+ // Instead of special casing only amd64, we treat this as an error on all
+ // 64-bit architectures so as to be future-proof.
+ if((int32)o < 0 && PtrSize > 4 && siz == 4) {
+ diag("non-pc-relative relocation address is too big: %#llux", o);
+ errorexit();
+ }
break;
- case D_PCREL:
+ case R_CALL:
+ case R_PCREL:
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
- if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != cursym->sect) {
+ if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != ctxt->cursym->sect) {
r->done = 0;
// set up addend for eventual relocation via outer symbol.
@@ -229,7 +268,7 @@ relocsym(Sym *s)
rs = rs->outer;
}
r->xadd -= r->siz; // relative to address after the relocated chunk
- if(rs->type != SHOSTOBJ && rs->sect == nil)
+ if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
diag("missing section for %s", rs->name);
r->xsym = rs;
@@ -242,7 +281,7 @@ relocsym(Sym *s)
o += symaddr(rs) - rs->sect->vaddr;
o -= r->off; // WTF?
} else {
- diag("unhandled pcrel relocation for %s", headtype);
+ diag("unhandled pcrel relocation for %s", headstring);
}
break;
}
@@ -257,17 +296,21 @@ relocsym(Sym *s)
// the standard host compiler (gcc on most other systems).
o += r->add - (s->value + r->off + (int32)r->siz);
break;
- case D_SIZE:
+ case R_SIZE:
o = r->sym->size + r->add;
break;
}
-//print("relocate %s %p %s => %p %p %p %p [%p]\n", s->name, s->value+off, r->sym ? r->sym->name : "<nil>", (void*)symaddr(r->sym), (void*)s->value, (void*)r->off, (void*)r->siz, (void*)o);
+//print("relocate %s %#llux (%#llux+%#llux, size %d) => %s %#llux +%#llx [%llx]\n", s->name, (uvlong)(s->value+off), (uvlong)s->value, (uvlong)r->off, r->siz, r->sym ? r->sym->name : "<nil>", (uvlong)symaddr(r->sym), (vlong)r->add, (vlong)o);
switch(siz) {
default:
- cursym = s;
+ ctxt->cursym = s;
diag("bad reloc size %#ux for %s", siz, r->sym->name);
+ case 1:
+ // TODO(rsc): Remove.
+ s->p[off] = (int8)o;
+ break;
case 4:
- if(r->type == D_PCREL) {
+ if(r->type == R_PCREL || r->type == R_CALL) {
if(o != (int32)o)
diag("pc-relative relocation address is too big: %#llx", o);
} else {
@@ -291,31 +334,35 @@ relocsym(Sym *s)
void
reloc(void)
{
- Sym *s;
+ LSym *s;
if(debug['v'])
Bprint(&bso, "%5.2f reloc\n", cputime());
Bflush(&bso);
- for(s=textp; s!=S; s=s->next)
+ for(s=ctxt->textp; s!=S; s=s->next)
relocsym(s);
for(s=datap; s!=S; s=s->next)
relocsym(s);
}
void
-dynrelocsym(Sym *s)
+dynrelocsym(LSym *s)
{
Reloc *r;
-
+
if(HEADTYPE == Hwindows) {
- Sym *rel, *targ;
+ LSym *rel, *targ;
- rel = lookup(".rel", 0);
+ rel = linklookup(ctxt, ".rel", 0);
if(s == rel)
return;
for(r=s->r; r<s->r+s->nr; r++) {
targ = r->sym;
+ if(targ == nil)
+ continue;
+ if(!targ->reachable)
+ diag("internal inconsistency: dynamic symbol %s is not reachable.", targ->name);
if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
targ->plt = rel->size;
r->sym = rel;
@@ -323,17 +370,17 @@ dynrelocsym(Sym *s)
// jmp *addr
if(thechar == '8') {
- adduint8(rel, 0xff);
- adduint8(rel, 0x25);
- addaddr(rel, targ);
- adduint8(rel, 0x90);
- adduint8(rel, 0x90);
+ adduint8(ctxt, rel, 0xff);
+ adduint8(ctxt, rel, 0x25);
+ addaddr(ctxt, rel, targ);
+ adduint8(ctxt, rel, 0x90);
+ adduint8(ctxt, rel, 0x90);
} else {
- adduint8(rel, 0xff);
- adduint8(rel, 0x24);
- adduint8(rel, 0x25);
- addaddrplus4(rel, targ, 0);
- adduint8(rel, 0x90);
+ adduint8(ctxt, rel, 0xff);
+ adduint8(ctxt, rel, 0x24);
+ adduint8(ctxt, rel, 0x25);
+ addaddrplus4(ctxt, rel, targ, 0);
+ adduint8(ctxt, rel, 0x90);
}
} else if(r->sym->plt >= 0) {
r->sym = rel;
@@ -344,15 +391,18 @@ dynrelocsym(Sym *s)
}
for(r=s->r; r<s->r+s->nr; r++) {
- if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256)
+ if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256) {
+ if(r->sym != S && !r->sym->reachable)
+ diag("internal inconsistency: dynamic symbol %s is not reachable.", r->sym->name);
adddynrel(s, r);
+ }
}
}
void
dynreloc(void)
{
- Sym *s;
+ LSym *s;
// -d suppresses dynamic loader format, so we may as well not
// compute these sections or mark their symbols as reachable.
@@ -362,7 +412,7 @@ dynreloc(void)
Bprint(&bso, "%5.2f reloc\n", cputime());
Bflush(&bso);
- for(s=textp; s!=S; s=s->next)
+ for(s=ctxt->textp; s!=S; s=s->next)
dynrelocsym(s);
for(s=datap; s!=S; s=s->next)
dynrelocsym(s);
@@ -370,118 +420,10 @@ dynreloc(void)
elfdynhash();
}
-void
-symgrow(Sym *s, int32 siz)
-{
- if(s->np >= siz)
- return;
-
- if(s->np > s->maxp) {
- cursym = s;
- diag("corrupt symbol data: np=%lld > maxp=%lld", (vlong)s->np, (vlong)s->maxp);
- errorexit();
- }
-
- if(s->maxp < siz) {
- if(s->maxp == 0)
- s->maxp = 8;
- while(s->maxp < siz)
- s->maxp <<= 1;
- s->p = erealloc(s->p, s->maxp);
- memset(s->p+s->np, 0, s->maxp-s->np);
- }
- s->np = siz;
-}
-
-void
-savedata(Sym *s, Prog *p, char *pn)
-{
- int32 off, siz, i, fl;
- uchar *cast;
- vlong o;
- Reloc *r;
-
- off = p->from.offset;
- siz = p->datasize;
- if(off < 0 || siz < 0 || off >= 1<<30 || siz >= 100)
- mangle(pn);
- symgrow(s, off+siz);
-
- switch(p->to.type) {
- default:
- diag("bad data: %P", p);
- break;
-
- case D_FCONST:
- switch(siz) {
- default:
- case 4:
- fl = ieeedtof(&p->to.ieee);
- cast = (uchar*)&fl;
- for(i=0; i<4; i++)
- s->p[off+i] = cast[fnuxi4[i]];
- break;
- case 8:
- cast = (uchar*)&p->to.ieee;
- for(i=0; i<8; i++)
- s->p[off+i] = cast[fnuxi8[i]];
- break;
- }
- break;
-
- case D_SCONST:
- for(i=0; i<siz; i++)
- s->p[off+i] = p->to.scon[i];
- break;
-
- case D_CONST:
- if(p->to.sym)
- goto Addr;
- o = p->to.offset;
- fl = o;
- cast = (uchar*)&fl;
- switch(siz) {
- default:
- 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;
- }
- break;
-
- case D_ADDR:
- case D_SIZE:
- Addr:
- r = addrel(s);
- r->off = off;
- r->siz = siz;
- r->sym = p->to.sym;
- r->type = p->to.type;
- if(r->type != D_SIZE)
- r->type = D_ADDR;
- r->add = p->to.offset;
- break;
- }
-}
-
static void
-blk(Sym *start, int32 addr, int32 size)
+blk(LSym *start, int32 addr, int32 size)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr;
uchar *p, *ep;
@@ -499,7 +441,7 @@ blk(Sym *start, int32 addr, int32 size)
diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
errorexit();
}
- cursym = sym;
+ ctxt->cursym = sym;
for(; addr < sym->value; addr++)
cput(0);
p = sym->p;
@@ -523,21 +465,20 @@ blk(Sym *start, int32 addr, int32 size)
void
codeblk(int32 addr, int32 size)
{
- Sym *sym;
- int32 eaddr, n, epc;
- Prog *p;
+ LSym *sym;
+ int32 eaddr, n;
uchar *q;
if(debug['a'])
Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());
- blk(textp, addr, size);
+ blk(ctxt->textp, addr, size);
/* again for printing */
if(!debug['a'])
return;
- for(sym = textp; sym != nil; sym = sym->next) {
+ for(sym = ctxt->textp; sym != nil; sym = sym->next) {
if(!sym->reachable)
continue;
if(sym->value >= addr)
@@ -557,36 +498,20 @@ codeblk(int32 addr, int32 size)
Bprint(&bso, " %.2ux", 0);
Bprint(&bso, "\n");
}
- p = sym->text;
- if(p == nil) {
- Bprint(&bso, "%.6llux\t%-20s | foreign text\n", (vlong)addr, sym->name);
- n = sym->size;
- q = sym->p;
-
- while(n >= 16) {
- Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q);
- addr += 16;
- q += 16;
- n -= 16;
- }
- if(n > 0)
- Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q);
- addr += n;
- continue;
- }
- Bprint(&bso, "%.6llux\t%-20s | %P\n", (vlong)sym->value, sym->name, p);
- for(p = p->link; p != P; p = p->link) {
- if(p->link != P)
- epc = p->link->pc;
- else
- epc = sym->value + sym->size;
- Bprint(&bso, "%.6llux\t", (uvlong)p->pc);
- q = sym->p + p->pc - sym->value;
- n = epc - p->pc;
- Bprint(&bso, "%-20.*I | %P\n", (int)n, q, p);
- addr += n;
+ Bprint(&bso, "%.6llux\t%-20s\n", (vlong)addr, sym->name);
+ n = sym->size;
+ q = sym->p;
+
+ while(n >= 16) {
+ Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q);
+ addr += 16;
+ q += 16;
+ n -= 16;
}
+ if(n > 0)
+ Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q);
+ addr += n;
}
if(addr < eaddr) {
@@ -600,7 +525,7 @@ codeblk(int32 addr, int32 size)
void
datblk(int32 addr, int32 size)
{
- Sym *sym;
+ LSym *sym;
int32 i, eaddr;
uchar *p, *ep;
char *typ, *rsname;
@@ -648,12 +573,15 @@ datblk(int32 addr, int32 size)
rsname = r->sym->name;
typ = "?";
switch(r->type) {
- case D_ADDR:
+ case R_ADDR:
typ = "addr";
break;
- case D_PCREL:
+ case R_PCREL:
typ = "pcrel";
break;
+ case R_CALL:
+ typ = "call";
+ break;
}
Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n",
(uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add));
@@ -682,28 +610,28 @@ strnput(char *s, int n)
void
addstrdata(char *name, char *value)
{
- Sym *s, *sp;
+ LSym *s, *sp;
char *p;
p = smprint("%s.str", name);
- sp = lookup(p, 0);
+ sp = linklookup(ctxt, p, 0);
free(p);
addstring(sp, value);
- s = lookup(name, 0);
+ s = linklookup(ctxt, name, 0);
s->size = 0;
s->dupok = 1;
- addaddr(s, sp);
- adduint32(s, strlen(value));
+ addaddr(ctxt, s, sp);
+ adduint32(ctxt, s, strlen(value));
if(PtrSize == 8)
- adduint32(s, 0); // round struct to pointer width
+ adduint32(ctxt, s, 0); // round struct to pointer width
// in case reachability has already been computed
sp->reachable = s->reachable;
}
vlong
-addstring(Sym *s, char *str)
+addstring(LSym *s, char *str)
{
int n;
int32 r;
@@ -715,230 +643,18 @@ addstring(Sym *s, char *str)
n = strlen(str)+1;
if(strcmp(s->name, ".shstrtab") == 0)
elfsetstring(str, r);
- symgrow(s, r+n);
+ symgrow(ctxt, s, r+n);
memmove(s->p+r, str, n);
s->size += n;
return r;
}
-vlong
-setuintxx(Sym *s, vlong off, uint64 v, vlong wid)
-{
- int32 i, fl;
- vlong o;
- uchar *cast;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- if(s->size < off+wid) {
- s->size = off+wid;
- symgrow(s, s->size);
- }
- fl = v;
- cast = (uchar*)&fl;
- switch(wid) {
- 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:
- o = v;
- cast = (uchar*)&o;
- for(i=0; i<8; i++)
- s->p[off+i] = cast[inuxi8[i]];
- break;
- }
- return off+wid;
-}
-
-vlong
-adduintxx(Sym *s, uint64 v, int wid)
-{
- vlong off;
-
- off = s->size;
- setuintxx(s, off, v, wid);
- return off;
-}
-
-vlong
-adduint8(Sym *s, uint8 v)
-{
- return adduintxx(s, v, 1);
-}
-
-vlong
-adduint16(Sym *s, uint16 v)
-{
- return adduintxx(s, v, 2);
-}
-
-vlong
-adduint32(Sym *s, uint32 v)
-{
- return adduintxx(s, v, 4);
-}
-
-vlong
-adduint64(Sym *s, uint64 v)
-{
- return adduintxx(s, v, 8);
-}
-
-vlong
-setuint8(Sym *s, vlong r, uint8 v)
-{
- return setuintxx(s, r, v, 1);
-}
-
-vlong
-setuint16(Sym *s, vlong r, uint16 v)
-{
- return setuintxx(s, r, v, 2);
-}
-
-vlong
-setuint32(Sym *s, vlong r, uint32 v)
-{
- return setuintxx(s, r, v, 4);
-}
-
-vlong
-setuint64(Sym *s, vlong r, uint64 v)
-{
- return setuintxx(s, r, v, 8);
-}
-
-vlong
-addaddrplus(Sym *s, Sym *t, vlong add)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += PtrSize;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->siz = PtrSize;
- r->type = D_ADDR;
- r->add = add;
- return i + r->siz;
-}
-
-static vlong
-addaddrplus4(Sym *s, Sym *t, vlong add)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += 4;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->siz = 4;
- r->type = D_ADDR;
- r->add = add;
- return i + r->siz;
-}
-
-vlong
-addpcrelplus(Sym *s, Sym *t, vlong add)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += 4;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->add = add;
- r->type = D_PCREL;
- r->siz = 4;
- return i + r->siz;
-}
-
-vlong
-addaddr(Sym *s, Sym *t)
-{
- return addaddrplus(s, t, 0);
-}
-
-vlong
-setaddrplus(Sym *s, vlong off, Sym *t, vlong add)
-{
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- if(off+PtrSize > s->size) {
- s->size = off + PtrSize;
- symgrow(s, s->size);
- }
- r = addrel(s);
- r->sym = t;
- r->off = off;
- r->siz = PtrSize;
- r->type = D_ADDR;
- r->add = add;
- return off + r->siz;
-}
-
-vlong
-setaddr(Sym *s, vlong off, Sym *t)
-{
- return setaddrplus(s, off, t, 0);
-}
-
-vlong
-addsize(Sym *s, Sym *t)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += PtrSize;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->siz = PtrSize;
- r->type = D_SIZE;
- return i + r->siz;
-}
-
void
dosymtype(void)
{
- Sym *s;
+ LSym *s;
- for(s = allsym; s != nil; s = s->allsym) {
+ for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(s->np > 0) {
if(s->type == SBSS)
s->type = SDATA;
@@ -949,7 +665,7 @@ dosymtype(void)
}
static int32
-symalign(Sym *s)
+symalign(LSym *s)
{
int32 align;
@@ -965,7 +681,7 @@ symalign(Sym *s)
}
static vlong
-aligndatsize(vlong datsize, Sym *s)
+aligndatsize(vlong datsize, LSym *s)
{
return rnd(datsize, symalign(s));
}
@@ -973,7 +689,7 @@ aligndatsize(vlong datsize, Sym *s)
// maxalign returns the maximum required alignment for
// the list of symbols s; the list stops when s->type exceeds type.
static int32
-maxalign(Sym *s, int type)
+maxalign(LSym *s, int type)
{
int32 align, max;
@@ -987,10 +703,10 @@ maxalign(Sym *s, int type)
}
static void
-gcaddsym(Sym *gc, Sym *s, vlong off)
+gcaddsym(LSym *gc, LSym *s, vlong off)
{
vlong a;
- Sym *gotype;
+ LSym *gotype;
if(s->size < PtrSize)
return;
@@ -1000,22 +716,22 @@ gcaddsym(Sym *gc, Sym *s, vlong off)
gotype = s->gotype;
if(gotype != nil) {
//print("gcaddsym: %s %d %s\n", s->name, s->size, gotype->name);
- adduintxx(gc, GC_CALL, PtrSize);
- adduintxx(gc, off, PtrSize);
- addpcrelplus(gc, decodetype_gc(gotype), 3*PtrSize+4);
+ adduintxx(ctxt, gc, GC_CALL, PtrSize);
+ adduintxx(ctxt, gc, off, PtrSize);
+ addpcrelplus(ctxt, gc, decodetype_gc(gotype), 3*PtrSize+4);
if(PtrSize == 8)
- adduintxx(gc, 0, 4);
+ adduintxx(ctxt, gc, 0, 4);
} else {
//print("gcaddsym: %s %d <unknown type>\n", s->name, s->size);
for(a = -off&(PtrSize-1); a+PtrSize<=s->size; a+=PtrSize) {
- adduintxx(gc, GC_APTR, PtrSize);
- adduintxx(gc, off+a, PtrSize);
+ adduintxx(ctxt, gc, GC_APTR, PtrSize);
+ adduintxx(ctxt, gc, off+a, PtrSize);
}
}
}
void
-growdatsize(vlong *datsizep, Sym *s)
+growdatsize(vlong *datsizep, LSym *s)
{
vlong datsize;
@@ -1034,27 +750,30 @@ dodata(void)
vlong datsize;
Section *sect;
Segment *segro;
- Sym *s, *last, **l;
- Sym *gcdata1, *gcbss1;
+ LSym *s, *last, **l;
+ LSym *gcdata1, *gcbss1;
if(debug['v'])
Bprint(&bso, "%5.2f dodata\n", cputime());
Bflush(&bso);
- gcdata1 = lookup("gcdata", 0);
- gcbss1 = lookup("gcbss", 0);
+ gcdata1 = linklookup(ctxt, "gcdata", 0);
+ gcbss1 = linklookup(ctxt, "gcbss", 0);
// size of .data and .bss section. the zero value is later replaced by the actual size of the section.
- adduintxx(gcdata1, 0, PtrSize);
- adduintxx(gcbss1, 0, PtrSize);
+ adduintxx(ctxt, gcdata1, 0, PtrSize);
+ adduintxx(ctxt, gcbss1, 0, PtrSize);
last = nil;
datap = nil;
- for(s=allsym; s!=S; s=s->allsym) {
+ for(s=ctxt->allsym; s!=S; s=s->allsym) {
if(!s->reachable || s->special)
continue;
if(STEXT < s->type && s->type < SXREF) {
+ if(s->onlist)
+ sysfatal("symbol %s listed multiple times", s->name);
+ s->onlist = 1;
if(last == nil)
datap = s;
else
@@ -1092,7 +811,7 @@ dodata(void)
}
*l = nil;
- datap = listsort(datap, datcmp, offsetof(Sym, next));
+ datap = listsort(datap, datcmp, offsetof(LSym, next));
/*
* allocate sections. list is sorted by type,
@@ -1128,8 +847,8 @@ dodata(void)
sect->align = maxalign(s, SINITARR-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("noptrdata", 0)->sect = sect;
- lookup("enoptrdata", 0)->sect = sect;
+ linklookup(ctxt, "noptrdata", 0)->sect = sect;
+ linklookup(ctxt, "enoptrdata", 0)->sect = sect;
for(; s != nil && s->type < SINITARR; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1159,11 +878,11 @@ dodata(void)
sect->align = maxalign(s, SBSS-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("data", 0)->sect = sect;
- lookup("edata", 0)->sect = sect;
+ linklookup(ctxt, "data", 0)->sect = sect;
+ linklookup(ctxt, "edata", 0)->sect = sect;
for(; s != nil && s->type < SBSS; s = s->next) {
if(s->type == SINITARR) {
- cursym = s;
+ ctxt->cursym = s;
diag("unexpected symbol type %d", s->type);
}
s->sect = sect;
@@ -1175,16 +894,16 @@ dodata(void)
}
sect->len = datsize - sect->vaddr;
- adduintxx(gcdata1, GC_END, PtrSize);
- setuintxx(gcdata1, 0, sect->len, PtrSize);
+ adduintxx(ctxt, gcdata1, GC_END, PtrSize);
+ setuintxx(ctxt, gcdata1, 0, sect->len, PtrSize);
/* bss */
sect = addsection(&segdata, ".bss", 06);
sect->align = maxalign(s, SNOPTRBSS-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("bss", 0)->sect = sect;
- lookup("ebss", 0)->sect = sect;
+ linklookup(ctxt, "bss", 0)->sect = sect;
+ linklookup(ctxt, "ebss", 0)->sect = sect;
for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
s->sect = sect;
datsize = aligndatsize(datsize, s);
@@ -1194,16 +913,16 @@ dodata(void)
}
sect->len = datsize - sect->vaddr;
- adduintxx(gcbss1, GC_END, PtrSize);
- setuintxx(gcbss1, 0, sect->len, PtrSize);
+ adduintxx(ctxt, gcbss1, GC_END, PtrSize);
+ setuintxx(ctxt, gcbss1, 0, sect->len, PtrSize);
/* pointer-free bss */
sect = addsection(&segdata, ".noptrbss", 06);
sect->align = maxalign(s, SNOPTRBSS);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("noptrbss", 0)->sect = sect;
- lookup("enoptrbss", 0)->sect = sect;
+ linklookup(ctxt, "noptrbss", 0)->sect = sect;
+ linklookup(ctxt, "enoptrbss", 0)->sect = sect;
for(; s != nil && s->type == SNOPTRBSS; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1211,7 +930,7 @@ dodata(void)
growdatsize(&datsize, s);
}
sect->len = datsize - sect->vaddr;
- lookup("end", 0)->sect = sect;
+ linklookup(ctxt, "end", 0)->sect = sect;
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
if(datsize != (uint32)datsize) {
@@ -1230,10 +949,18 @@ dodata(void)
growdatsize(&datsize, s);
}
sect->len = datsize;
+ } else {
+ // Might be internal linking but still using cgo.
+ // In that case, the only possible STLSBSS symbol is tlsgm.
+ // Give it offset 0, because it's the only thing here.
+ if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsgm") == 0) {
+ s->value = 0;
+ s = s->next;
+ }
}
if(s != nil) {
- cursym = nil;
+ ctxt->cursym = nil;
diag("unexpected symbol type %d for %s", s->type, s->name);
}
@@ -1274,8 +1001,8 @@ dodata(void)
sect->align = maxalign(s, STYPELINK-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = 0;
- lookup("rodata", 0)->sect = sect;
- lookup("erodata", 0)->sect = sect;
+ linklookup(ctxt, "rodata", 0)->sect = sect;
+ linklookup(ctxt, "erodata", 0)->sect = sect;
for(; s != nil && s->type < STYPELINK; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1290,8 +1017,8 @@ dodata(void)
sect->align = maxalign(s, STYPELINK);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("typelink", 0)->sect = sect;
- lookup("etypelink", 0)->sect = sect;
+ linklookup(ctxt, "typelink", 0)->sect = sect;
+ linklookup(ctxt, "etypelink", 0)->sect = sect;
for(; s != nil && s->type == STYPELINK; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1306,8 +1033,8 @@ dodata(void)
sect->align = maxalign(s, SPCLNTAB-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("symtab", 0)->sect = sect;
- lookup("esymtab", 0)->sect = sect;
+ linklookup(ctxt, "symtab", 0)->sect = sect;
+ linklookup(ctxt, "esymtab", 0)->sect = sect;
for(; s != nil && s->type < SPCLNTAB; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1322,8 +1049,8 @@ dodata(void)
sect->align = maxalign(s, SELFROSECT-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("pclntab", 0)->sect = sect;
- lookup("epclntab", 0)->sect = sect;
+ linklookup(ctxt, "pclntab", 0)->sect = sect;
+ linklookup(ctxt, "epclntab", 0)->sect = sect;
for(; s != nil && s->type < SELFROSECT; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1366,9 +1093,8 @@ void
textaddress(void)
{
uvlong va;
- Prog *p;
Section *sect;
- Sym *sym, *sub;
+ LSym *sym, *sub;
addsection(&segtext, ".text", 05);
@@ -1376,28 +1102,24 @@ textaddress(void)
// Could parallelize, by assigning to text
// and then letting threads copy down, but probably not worth it.
sect = segtext.sect;
- sect->align = FuncAlign;
- lookup("text", 0)->sect = sect;
- lookup("etext", 0)->sect = sect;
+ sect->align = funcalign;
+ linklookup(ctxt, "text", 0)->sect = sect;
+ linklookup(ctxt, "etext", 0)->sect = sect;
va = INITTEXT;
sect->vaddr = va;
- for(sym = textp; sym != nil; sym = sym->next) {
+ for(sym = ctxt->textp; sym != nil; sym = sym->next) {
sym->sect = sect;
if(sym->type & SSUB)
continue;
if(sym->align != 0)
va = rnd(va, sym->align);
- else if(sym->text != P)
- va = rnd(va, FuncAlign);
+ else
+ va = rnd(va, funcalign);
sym->value = 0;
- for(sub = sym; sub != S; sub = sub->sub) {
+ for(sub = sym; sub != S; sub = sub->sub)
sub->value += va;
- for(p = sub->text; p != P; p = p->link)
- p->pc += sub->value;
- }
- if(sym->size == 0 && sym->sub != S) {
- cursym = sym;
- }
+ if(sym->size == 0 && sym->sub != S)
+ ctxt->cursym = sym;
va += sym->size;
}
sect->len = va - sect->vaddr;
@@ -1409,7 +1131,7 @@ address(void)
{
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
Section *typelink;
- Sym *sym, *sub;
+ LSym *sym, *sub;
uvlong va;
vlong vlen;
@@ -1418,13 +1140,14 @@ address(void)
segtext.vaddr = va;
segtext.fileoff = HEADR;
for(s=segtext.sect; s != nil; s=s->next) {
-//print("%s at %#llux + %#llux\n", s->name, va, (vlong)s->len);
va = rnd(va, s->align);
s->vaddr = va;
va += s->len;
}
segtext.len = va - INITTEXT;
segtext.filelen = segtext.len;
+ if(HEADTYPE == Hnacl)
+ va += 32; // room for the "halt sled"
if(segrodata.sect != nil) {
// align to page boundary so as not to mix
@@ -1451,7 +1174,7 @@ address(void)
segdata.filelen = 0;
if(HEADTYPE == Hwindows)
segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN);
- if(HEADTYPE == Hplan9x64 || HEADTYPE == Hplan9x32)
+ if(HEADTYPE == Hplan9)
segdata.fileoff = segtext.fileoff + segtext.filelen;
data = nil;
noptr = nil;
@@ -1485,8 +1208,9 @@ address(void)
pclntab = symtab->next;
for(sym = datap; sym != nil; sym = sym->next) {
- cursym = sym;
- sym->value += sym->sect->vaddr;
+ ctxt->cursym = sym;
+ if(sym->sect != nil)
+ sym->value += sym->sect->vaddr;
for(sub = sym->sub; sub != nil; sub = sub->sub)
sub->value += sym->value;
}
@@ -1498,13 +1222,13 @@ address(void)
xdefine("typelink", SRODATA, typelink->vaddr);
xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len);
- sym = lookup("gcdata", 0);
+ sym = linklookup(ctxt, "gcdata", 0);
xdefine("egcdata", SRODATA, symaddr(sym) + sym->size);
- lookup("egcdata", 0)->sect = sym->sect;
+ linklookup(ctxt, "egcdata", 0)->sect = sym->sect;
- sym = lookup("gcbss", 0);
+ sym = linklookup(ctxt, "gcbss", 0);
xdefine("egcbss", SRODATA, symaddr(sym) + sym->size);
- lookup("egcbss", 0)->sect = sym->sect;
+ linklookup(ctxt, "egcbss", 0)->sect = sym->sect;
xdefine("symtab", SRODATA, symtab->vaddr);
xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
diff --git a/src/cmd/ld/decodesym.c b/src/cmd/ld/decodesym.c
index ab3f4fbd5..da48d3786 100644
--- a/src/cmd/ld/decodesym.c
+++ b/src/cmd/ld/decodesym.c
@@ -11,7 +11,7 @@
// ../gc/reflect.c stuffs in these.
static Reloc*
-decode_reloc(Sym *s, int32 off)
+decode_reloc(LSym *s, int32 off)
{
int i;
@@ -21,8 +21,8 @@ decode_reloc(Sym *s, int32 off)
return nil;
}
-static Sym*
-decode_reloc_sym(Sym *s, int32 off)
+static LSym*
+decode_reloc_sym(LSym *s, int32 off)
{
Reloc *r;
@@ -67,103 +67,109 @@ decode_inuxi(uchar* p, int sz)
return l;
}
+static int
+commonsize(void)
+{
+ return 7*PtrSize + 8;
+}
+
// Type.commonType.kind
uint8
-decodetype_kind(Sym *s)
+decodetype_kind(LSym *s)
{
return s->p[1*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
}
// Type.commonType.size
vlong
-decodetype_size(Sym *s)
+decodetype_size(LSym *s)
{
return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10
}
// Type.commonType.gc
-Sym*
-decodetype_gc(Sym *s)
+LSym*
+decodetype_gc(LSym *s)
{
return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
}
// Type.ArrayType.elem and Type.SliceType.Elem
-Sym*
-decodetype_arrayelem(Sym *s)
+LSym*
+decodetype_arrayelem(LSym *s)
{
- return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
+ return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30
}
vlong
-decodetype_arraylen(Sym *s)
+decodetype_arraylen(LSym *s)
{
- return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
+ return decode_inuxi(s->p + commonsize()+PtrSize, PtrSize);
}
// Type.PtrType.elem
-Sym*
-decodetype_ptrelem(Sym *s)
+LSym*
+decodetype_ptrelem(LSym *s)
{
- return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
+ return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30
}
// Type.MapType.key, elem
-Sym*
-decodetype_mapkey(Sym *s)
+LSym*
+decodetype_mapkey(LSym *s)
{
- return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
+ return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30
}
-Sym*
-decodetype_mapvalue(Sym *s)
+LSym*
+decodetype_mapvalue(LSym *s)
{
- return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
+ return decode_reloc_sym(s, commonsize()+PtrSize); // 0x20 / 0x38
}
// Type.ChanType.elem
-Sym*
-decodetype_chanelem(Sym *s)
+LSym*
+decodetype_chanelem(LSym *s)
{
- return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
+ return decode_reloc_sym(s, commonsize()); // 0x1c / 0x30
}
// Type.FuncType.dotdotdot
int
-decodetype_funcdotdotdot(Sym *s)
+decodetype_funcdotdotdot(LSym *s)
{
- return s->p[CommonSize];
+ return s->p[commonsize()];
}
// Type.FuncType.in.len
int
-decodetype_funcincount(Sym *s)
+decodetype_funcincount(LSym *s)
{
- return decode_inuxi(s->p + CommonSize+2*PtrSize, IntSize);
+ return decode_inuxi(s->p + commonsize()+2*PtrSize, IntSize);
}
int
-decodetype_funcoutcount(Sym *s)
+decodetype_funcoutcount(LSym *s)
{
- return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*IntSize, IntSize);
+ return decode_inuxi(s->p + commonsize()+3*PtrSize + 2*IntSize, IntSize);
}
-Sym*
-decodetype_funcintype(Sym *s, int i)
+LSym*
+decodetype_funcintype(LSym *s, int i)
{
Reloc *r;
- r = decode_reloc(s, CommonSize + PtrSize);
+ r = decode_reloc(s, commonsize() + PtrSize);
if (r == nil)
return nil;
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
}
-Sym*
-decodetype_funcouttype(Sym *s, int i)
+LSym*
+decodetype_funcouttype(LSym *s, int i)
{
Reloc *r;
- r = decode_reloc(s, CommonSize + 2*PtrSize + 2*IntSize);
+ r = decode_reloc(s, commonsize() + 2*PtrSize + 2*IntSize);
if (r == nil)
return nil;
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
@@ -171,22 +177,25 @@ decodetype_funcouttype(Sym *s, int i)
// Type.StructType.fields.Slice::len
int
-decodetype_structfieldcount(Sym *s)
+decodetype_structfieldcount(LSym *s)
+{
+ return decode_inuxi(s->p + commonsize() + PtrSize, IntSize);
+}
+
+static int
+structfieldsize(void)
{
- return decode_inuxi(s->p + CommonSize + PtrSize, IntSize);
+ return 5*PtrSize;
}
-enum {
- StructFieldSize = 5*PtrSize
-};
// Type.StructType.fields[]-> name, typ and offset.
char*
-decodetype_structfieldname(Sym *s, int i)
+decodetype_structfieldname(LSym *s, int i)
{
Reloc *r;
// go.string."foo" 0x28 / 0x40
- s = decode_reloc_sym(s, CommonSize + PtrSize + 2*IntSize + i*StructFieldSize);
+ s = decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize());
if (s == nil) // embedded structs have a nil name.
return nil;
r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0
@@ -195,21 +204,21 @@ decodetype_structfieldname(Sym *s, int i)
return (char*) r->sym->p + r->add; // the c-string
}
-Sym*
-decodetype_structfieldtype(Sym *s, int i)
+LSym*
+decodetype_structfieldtype(LSym *s, int i)
{
- return decode_reloc_sym(s, CommonSize + PtrSize + 2*IntSize + i*StructFieldSize + 2*PtrSize);
+ return decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 2*PtrSize);
}
vlong
-decodetype_structfieldoffs(Sym *s, int i)
+decodetype_structfieldoffs(LSym *s, int i)
{
- return decode_inuxi(s->p + CommonSize + PtrSize + 2*IntSize + i*StructFieldSize + 4*PtrSize, IntSize);
+ return decode_inuxi(s->p + commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 4*PtrSize, IntSize);
}
// InterfaceTYpe.methods.len
vlong
-decodetype_ifacemethodcount(Sym *s)
+decodetype_ifacemethodcount(LSym *s)
{
- return decode_inuxi(s->p + CommonSize + PtrSize, IntSize);
+ return decode_inuxi(s->p + commonsize() + PtrSize, IntSize);
}
diff --git a/src/cmd/ld/doc.go b/src/cmd/ld/doc.go
index 2adda25f2..8135bd549 100644
--- a/src/cmd/ld/doc.go
+++ b/src/cmd/ld/doc.go
@@ -43,6 +43,8 @@ Options new in this version:
Write NetBSD ELF binaries (default when $GOOS is netbsd)
-H openbsd (only in 6l/8l)
Write OpenBSD ELF binaries (default when $GOOS is openbsd)
+ -H solaris (only in 6l)
+ Write Solaris ELF binaries (default when $GOOS is solaris)
-H windows (only in 6l/8l)
Write Windows PE32+ Console binaries (default when $GOOS is windows)
-H windowsgui (only in 6l/8l)
@@ -58,6 +60,8 @@ Options new in this version:
Omit the symbol table and debug information.
-V
Print the linker version.
+ -w
+ Omit the DWARF symbol table.
-X symbol value
Set the value of an otherwise uninitialized string variable.
The symbol name should be of the form importpath.name,
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index c832bcc94..cc77b45cd 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -27,19 +27,19 @@
static vlong abbrevo;
static vlong abbrevsize;
-static Sym* abbrevsym;
+static LSym* abbrevsym;
static vlong abbrevsympos;
static vlong lineo;
static vlong linesize;
-static Sym* linesym;
+static LSym* linesym;
static vlong linesympos;
static vlong infoo; // also the base for DWDie->offs and reference attributes.
static vlong infosize;
-static Sym* infosym;
+static LSym* infosym;
static vlong infosympos;
static vlong frameo;
static vlong framesize;
-static Sym* framesym;
+static LSym* framesym;
static vlong framesympos;
static vlong pubnameso;
static vlong pubnamessize;
@@ -50,19 +50,19 @@ static vlong arangessize;
static vlong gdbscripto;
static vlong gdbscriptsize;
-static Sym *infosec;
+static LSym *infosec;
static vlong inforeloco;
static vlong inforelocsize;
-static Sym *arangessec;
+static LSym *arangessec;
static vlong arangesreloco;
static vlong arangesrelocsize;
-static Sym *linesec;
+static LSym *linesec;
static vlong linereloco;
static vlong linerelocsize;
-static Sym *framesec;
+static LSym *framesec;
static vlong framereloco;
static vlong framerelocsize;
@@ -594,7 +594,7 @@ find_or_diag(DWDie *die, char* name)
}
static void
-adddwarfrel(Sym* sec, Sym* sym, vlong offsetbase, int siz, vlong addend)
+adddwarfrel(LSym* sec, LSym* sym, vlong offsetbase, int siz, vlong addend)
{
Reloc *r;
@@ -603,7 +603,7 @@ adddwarfrel(Sym* sec, Sym* sym, vlong offsetbase, int siz, vlong addend)
r->xsym = sym;
r->off = cpos() - offsetbase;
r->siz = siz;
- r->type = D_ADDR;
+ r->type = R_ADDR;
r->add = addend;
r->xadd = addend;
if(iself && thechar == '6')
@@ -639,8 +639,8 @@ putattr(int abbrev, int form, int cls, vlong value, char *data)
switch(form) {
case DW_FORM_addr: // address
if(linkmode == LinkExternal) {
- value -= ((Sym*)data)->value;
- adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
+ value -= ((LSym*)data)->value;
+ adddwarfrel(infosec, (LSym*)data, infoo, PtrSize, value);
break;
}
addrput(value);
@@ -651,8 +651,8 @@ putattr(int abbrev, int form, int cls, vlong value, char *data)
cput(1+PtrSize);
cput(DW_OP_addr);
if(linkmode == LinkExternal) {
- value -= ((Sym*)data)->value;
- adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
+ value -= ((LSym*)data)->value;
+ adddwarfrel(infosec, (LSym*)data, infoo, PtrSize, value);
break;
}
addrput(value);
@@ -847,7 +847,7 @@ newmemberoffsetattr(DWDie *die, int32 offs)
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
// location expression that evals to a const.
static void
-newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
+newabslocexprattr(DWDie *die, vlong addr, LSym *sym)
{
newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
}
@@ -864,12 +864,12 @@ enum {
static DWDie* defptrto(DWDie *dwtype); // below
// Lookup predefined types
-static Sym*
+static LSym*
lookup_or_diag(char *n)
{
- Sym *s;
+ LSym *s;
- s = rlookup(n, 0);
+ s = linkrlookup(ctxt, n, 0);
if (s == nil || s->size == 0) {
diag("dwarf: missing type: %s", n);
errorexit();
@@ -904,10 +904,10 @@ dotypedef(DWDie *parent, char *name, DWDie *def)
// Define gotype, for composite ones recurse into constituents.
static DWDie*
-defgotype(Sym *gotype)
+defgotype(LSym *gotype)
{
DWDie *die, *fld;
- Sym *s;
+ LSym *s;
char *name, *f;
uint8 kind;
vlong bytesize;
@@ -1099,21 +1099,29 @@ defptrto(DWDie *dwtype)
}
// Copies src's children into dst. Copies attributes by value.
-// DWAttr.data is copied as pointer only.
+// DWAttr.data is copied as pointer only. If except is one of
+// the top-level children, it will not be copied.
static void
-copychildren(DWDie *dst, DWDie *src)
+copychildrenexcept(DWDie *dst, DWDie *src, DWDie *except)
{
DWDie *c;
DWAttr *a;
for (src = src->child; src != nil; src = src->link) {
+ if(src == except)
+ continue;
c = newdie(dst, src->abbrev, getattr(src, DW_AT_name)->data);
for (a = src->attr; a != nil; a = a->link)
newattr(c, a->atr, a->cls, a->value, a->data);
- copychildren(c, src);
+ copychildrenexcept(c, src, nil);
}
reverselist(&dst->child);
}
+static void
+copychildren(DWDie *dst, DWDie *src)
+{
+ copychildrenexcept(dst, src, nil);
+}
// Search children (assumed to have DW_TAG_member) for the one named
// field and set its DW_AT_type to dwtype
@@ -1253,7 +1261,10 @@ synthesizemaptypes(DWDie *die)
mkinternaltypename("bucket",
getattr(keytype, DW_AT_name)->data,
getattr(valtype, DW_AT_name)->data));
- copychildren(dwhb, bucket);
+ // Copy over all fields except the field "data" from the generic bucket.
+ // "data" will be replaced with keys/values below.
+ copychildrenexcept(dwhb, bucket, find(bucket, "data"));
+
fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys");
newrefattr(fld, DW_AT_type, dwhk);
newmemberoffsetattr(fld, BucketSize + PtrSize);
@@ -1335,7 +1346,7 @@ synthesizechantypes(DWDie *die)
// For use with pass.c::genasmsym
static void
-defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
+defdwsymb(LSym* sym, char *s, int t, vlong v, vlong size, int ver, LSym *gotype)
{
DWDie *dv, *dt;
@@ -1371,284 +1382,37 @@ defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
newrefattr(dv, DW_AT_type, dt);
}
-// TODO(lvd) For now, just append them all to the first compilation
-// unit (that should be main), in the future distribute them to the
-// appropriate compilation units.
static void
movetomodule(DWDie *parent)
{
DWDie *die;
- for (die = dwroot.child->child; die->link != nil; die = die->link) /* nix */;
+ die = dwroot.child->child;
+ while(die->link != nil)
+ die = die->link;
die->link = parent->child;
}
-/*
- * Filename fragments for the line history stack.
- */
-
-static char **ftab;
-static int ftabsize;
-
-void
-dwarfaddfrag(int n, char *frag)
-{
- int s;
-
- if (n >= ftabsize) {
- s = ftabsize;
- ftabsize = 1 + n + (n >> 2);
- ftab = erealloc(ftab, ftabsize * sizeof(ftab[0]));
- memset(ftab + s, 0, (ftabsize - s) * sizeof(ftab[0]));
- }
-
- if (*frag == '<')
- frag++;
- ftab[n] = frag;
-}
-
-// Returns a malloc'ed string, piecewise copied from the ftab.
-static char *
-decodez(char *s)
-{
- int len, o;
- char *ss, *f;
- char *r, *rb, *re;
-
- len = 0;
- ss = s + 1; // first is 0
- while((o = ((uint8)ss[0] << 8) | (uint8)ss[1]) != 0) {
- if (o < 0 || o >= ftabsize) {
- diag("dwarf: corrupt z entry");
- return 0;
- }
- f = ftab[o];
- if (f == nil) {
- diag("dwarf: corrupt z entry");
- return 0;
- }
- len += strlen(f) + 1; // for the '/'
- ss += 2;
- }
-
- if (len == 0)
- return 0;
-
- r = malloc(len + 1);
- if(r == nil) {
- diag("out of memory");
- errorexit();
- }
- rb = r;
- re = rb + len + 1;
-
- s++;
- while((o = ((uint8)s[0] << 8) | (uint8)s[1]) != 0) {
- f = ftab[o];
- if (rb == r || rb[-1] == '/')
- rb = seprint(rb, re, "%s", f);
- else
- rb = seprint(rb, re, "/%s", f);
- s += 2;
- }
- return r;
-}
-
-/*
- * The line history itself
- */
-
-static char **histfile; // [0] holds "<eof>", DW_LNS_set_file arguments must be > 0.
-static int histfilesize;
-static int histfilecap;
-
+// If the pcln table contains runtime/string.goc, use that to set gdbscript path.
static void
-clearhistfile(void)
+finddebugruntimepath(LSym *s)
{
int i;
+ char *p;
+ LSym *f;
+
+ if(gdbscript[0] != '\0')
+ return;
- // [0] holds "<eof>"
- for (i = 1; i < histfilesize; i++)
- free(histfile[i]);
- histfilesize = 0;
-}
-
-static int
-addhistfile(char *zentry)
-{
- char *fname;
-
- if (histfilesize == histfilecap) {
- histfilecap = 2 * histfilecap + 2;
- histfile = erealloc(histfile, histfilecap * sizeof(char*));
- }
- if (histfilesize == 0)
- histfile[histfilesize++] = "<eof>";
-
- fname = decodez(zentry);
-// print("addhistfile %d: %s\n", histfilesize, fname);
- if (fname == 0)
- return -1;
-
- // Don't fill with duplicates (check only top one).
- if (strcmp(fname, histfile[histfilesize-1]) == 0) {
- free(fname);
- return histfilesize - 1;
- }
-
- histfile[histfilesize++] = fname;
- return histfilesize - 1;
-}
-
-// if the histfile stack contains ..../runtime/runtime_defs.go
-// use that to set gdbscript
-static void
-finddebugruntimepath(void)
-{
- int i, l;
- char *c;
-
- for (i = 1; i < histfilesize; i++) {
- if ((c = strstr(histfile[i], "runtime/zruntime_defs")) != nil) {
- l = c - histfile[i];
- memmove(gdbscript, histfile[i], l);
- memmove(gdbscript + l, "runtime/runtime-gdb.py", strlen("runtime/runtime-gdb.py") + 1);
- break;
- }
- }
-}
-
-// Go's runtime C sources are sane, and Go sources nest only 1 level,
-// so a handful would be plenty, if it weren't for the fact that line
-// directives can push an unlimited number of them.
-static struct {
- int file;
- vlong line;
-} *includestack;
-static int includestacksize;
-static int includetop;
-static vlong absline;
-
-typedef struct Linehist Linehist;
-struct Linehist {
- Linehist *link;
- vlong absline;
- vlong line;
- int file;
-};
-
-static Linehist *linehist;
-
-static void
-checknesting(void)
-{
- if (includetop < 0) {
- diag("dwarf: corrupt z stack");
- errorexit();
- }
- if (includetop >= includestacksize) {
- includestacksize += 1;
- includestacksize <<= 2;
-// print("checknesting: growing to %d\n", includestacksize);
- includestack = erealloc(includestack, includestacksize * sizeof *includestack);
- }
-}
-
-/*
- * Return false if the a->link chain contains no history, otherwise
- * returns true and finds z and Z entries in the Auto list (of a
- * Prog), and resets the history stack
- */
-static int
-inithist(Auto *a)
-{
- Linehist *lh;
-
- for (; a; a = a->link)
- if (a->type == D_FILE)
+ for(i=0; i<s->pcln->nfile; i++) {
+ f = s->pcln->file[i];
+ if((p = strstr(f->name, "runtime/string.goc")) != nil) {
+ *p = '\0';
+ snprint(gdbscript, sizeof gdbscript, "%sruntime/runtime-gdb.py", f->name);
+ *p = 'r';
break;
- if (a==nil)
- return 0;
-
- // We have a new history. They are guaranteed to come completely
- // at the beginning of the compilation unit.
- if (a->aoffset != 1) {
- diag("dwarf: stray 'z' with offset %d", a->aoffset);
- return 0;
- }
-
- // Clear the history.
- clearhistfile();
- includetop = 0;
- checknesting();
- includestack[includetop].file = 0;
- includestack[includetop].line = -1;
- absline = 0;
- while (linehist != nil) {
- lh = linehist->link;
- free(linehist);
- linehist = lh;
- }
-
- // Construct the new one.
- for (; a; a = a->link) {
- if (a->type == D_FILE) { // 'z'
- int f = addhistfile(a->asym->name);
- if (f < 0) { // pop file
- includetop--;
- checknesting();
- } else { // pushed a file (potentially same)
- includestack[includetop].line += a->aoffset - absline;
- includetop++;
- checknesting();
- includestack[includetop].file = f;
- includestack[includetop].line = 1;
- }
- absline = a->aoffset;
- } else if (a->type == D_FILE1) { // 'Z'
- // We could just fixup the current
- // linehist->line, but there doesn't appear to
- // be a guarantee that every 'Z' is preceded
- // by its own 'z', so do the safe thing and
- // update the stack and push a new Linehist
- // entry
- includestack[includetop].line = a->aoffset;
- } else
- continue;
- if (linehist == 0 || linehist->absline != absline) {
- Linehist* lh = malloc(sizeof *lh);
- if(lh == nil) {
- diag("out of memory");
- errorexit();
- }
- lh->link = linehist;
- lh->absline = absline;
- linehist = lh;
}
- linehist->file = includestack[includetop].file;
- linehist->line = includestack[includetop].line;
}
- return 1;
-}
-
-static Linehist *
-searchhist(vlong absline)
-{
- Linehist *lh;
-
- for (lh = linehist; lh; lh = lh->link)
- if (lh->absline <= absline)
- break;
- return lh;
-}
-
-static int
-guesslang(char *s)
-{
- if(strlen(s) >= 3 && strcmp(s+strlen(s)-3, ".go") == 0)
- return DW_LANG_Go;
-
- return DW_LANG_C;
}
/*
@@ -1659,7 +1423,7 @@ guesslang(char *s)
enum {
LINE_BASE = -1,
LINE_RANGE = 4,
- OPCODE_BASE = 5
+ OPCODE_BASE = 10
};
static void
@@ -1719,7 +1483,7 @@ mkvarname(char* name, int da)
// flush previous compilation unit.
static void
-flushunit(DWDie *dwinfo, vlong pc, Sym *pcsym, vlong unitstart, int32 header_length)
+flushunit(DWDie *dwinfo, vlong pc, LSym *pcsym, vlong unitstart, int32 header_length)
{
vlong here;
@@ -1744,147 +1508,129 @@ flushunit(DWDie *dwinfo, vlong pc, Sym *pcsym, vlong unitstart, int32 header_len
static void
writelines(void)
{
- Prog *q;
- Sym *s, *epcs;
+ LSym *s, *epcs;
Auto *a;
vlong unitstart, headerend, offs;
- vlong pc, epc, lc, llc, lline;
- int currfile;
- int i, lang, da, dt;
- Linehist *lh;
+ vlong pc, epc;
+ int i, lang, da, dt, line, file;
DWDie *dwinfo, *dwfunc, *dwvar, **dws;
DWDie *varhash[HASHSIZE];
char *n, *nn;
+ Pciter pcfile, pcline;
+ LSym **files, *f;
if(linesec == S)
- linesec = lookup(".dwarfline", 0);
+ linesec = linklookup(ctxt, ".dwarfline", 0);
linesec->nr = 0;
unitstart = -1;
headerend = -1;
- pc = 0;
epc = 0;
epcs = S;
- lc = 1;
- llc = 1;
- currfile = -1;
lineo = cpos();
dwinfo = nil;
+
+ flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
+ unitstart = cpos();
+
+ lang = DW_LANG_Go;
+
+ s = ctxt->textp;
+
+ dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup("go"));
+ newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
+ newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
+ newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);
+
+ // Write .debug_line Line Number Program Header (sec 6.2.4)
+ // Fields marked with (*) must be changed for 64-bit dwarf
+ LPUT(0); // unit_length (*), will be filled in by flushunit.
+ WPUT(2); // dwarf version (appendix F)
+ LPUT(0); // header_length (*), filled in by flushunit.
+ // cpos == unitstart + 4 + 2 + 4
+ cput(1); // minimum_instruction_length
+ cput(1); // default_is_stmt
+ cput(LINE_BASE); // line_base
+ cput(LINE_RANGE); // line_range
+ cput(OPCODE_BASE); // opcode_base
+ cput(0); // standard_opcode_lengths[1]
+ cput(1); // standard_opcode_lengths[2]
+ cput(1); // standard_opcode_lengths[3]
+ cput(1); // standard_opcode_lengths[4]
+ cput(1); // standard_opcode_lengths[5]
+ cput(0); // standard_opcode_lengths[6]
+ cput(0); // standard_opcode_lengths[7]
+ cput(0); // standard_opcode_lengths[8]
+ cput(1); // standard_opcode_lengths[9]
+ cput(0); // include_directories (empty)
+
+ files = emallocz(ctxt->nhistfile*sizeof files[0]);
+ for(f = ctxt->filesyms; f != nil; f = f->next)
+ files[f->value-1] = f;
+
+ for(i=0; i<ctxt->nhistfile; i++) {
+ strnput(files[i]->name, strlen(files[i]->name) + 4);
+ // 4 zeros: the string termination + 3 fields.
+ }
+
+ cput(0); // terminate file_names.
+ headerend = cpos();
+
+ cput(0); // start extended opcode
+ uleb128put(1 + PtrSize);
+ cput(DW_LNE_set_address);
+
+ pc = s->value;
+ line = 1;
+ file = 1;
+ if(linkmode == LinkExternal)
+ adddwarfrel(linesec, s, lineo, PtrSize, 0);
+ else
+ addrput(pc);
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- s = cursym;
- if(s->text == P)
- continue;
-
- // Look for history stack. If we find one,
- // we're entering a new compilation unit
-
- if (inithist(s->autom)) {
- flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
- unitstart = cpos();
-
- if(debug['v'] > 1) {
- print("dwarf writelines found %s\n", histfile[1]);
- Linehist* lh;
- for (lh = linehist; lh; lh = lh->link)
- print("\t%8lld: [%4lld]%s\n",
- lh->absline, lh->line, histfile[lh->file]);
- }
-
- lang = guesslang(histfile[1]);
- finddebugruntimepath();
-
- dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup(histfile[1]));
- newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
- newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
- newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, (char*)s);
-
- // Write .debug_line Line Number Program Header (sec 6.2.4)
- // Fields marked with (*) must be changed for 64-bit dwarf
- LPUT(0); // unit_length (*), will be filled in by flushunit.
- WPUT(2); // dwarf version (appendix F)
- LPUT(0); // header_length (*), filled in by flushunit.
- // cpos == unitstart + 4 + 2 + 4
- cput(1); // minimum_instruction_length
- cput(1); // default_is_stmt
- cput(LINE_BASE); // line_base
- cput(LINE_RANGE); // line_range
- cput(OPCODE_BASE); // opcode_base (we only use 1..4)
- cput(0); // standard_opcode_lengths[1]
- cput(1); // standard_opcode_lengths[2]
- cput(1); // standard_opcode_lengths[3]
- cput(1); // standard_opcode_lengths[4]
- cput(0); // include_directories (empty)
-
- for (i=1; i < histfilesize; i++) {
- strnput(histfile[i], strlen(histfile[i]) + 4);
- // 4 zeros: the string termination + 3 fields.
- }
-
- cput(0); // terminate file_names.
- headerend = cpos();
-
- pc = s->text->pc;
- epc = pc;
- epcs = s;
- currfile = 1;
- lc = 1;
- llc = 1;
-
- cput(0); // start extended opcode
- uleb128put(1 + PtrSize);
- cput(DW_LNE_set_address);
-
- if(linkmode == LinkExternal)
- adddwarfrel(linesec, s, lineo, PtrSize, 0);
- else
- addrput(pc);
- }
- if(s->text == nil)
- continue;
-
- if (unitstart < 0) {
- diag("dwarf: reachable code before seeing any history: %P", s->text);
- continue;
- }
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
+ s = ctxt->cursym;
dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);
epc = s->value + s->size;
+ epcs = s;
newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, (char*)s);
if (s->version == 0)
newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
- if(s->text->link == nil)
+ if(s->pcln == nil)
continue;
- for(q = s->text; q != P; q = q->link) {
- lh = searchhist(q->line);
- if (lh == nil) {
- diag("dwarf: corrupt history or bad absolute line: %P", q);
+ finddebugruntimepath(s);
+
+ pciterinit(ctxt, &pcfile, &s->pcln->pcfile);
+ pciterinit(ctxt, &pcline, &s->pcln->pcline);
+ epc = pc;
+ while(!pcfile.done && !pcline.done) {
+ if(epc - s->value >= pcfile.nextpc) {
+ pciternext(&pcfile);
continue;
}
-
- if (lh->file < 1) { // 0 is the past-EOF entry.
- // diag("instruction with line number past EOF in %s: %P", histfile[1], q);
+ if(epc - s->value >= pcline.nextpc) {
+ pciternext(&pcline);
continue;
}
- lline = lh->line + q->line - lh->absline;
- if (debug['v'] > 1)
- print("%6llux %s[%lld] %P\n", (vlong)q->pc, histfile[lh->file], lline, q);
-
- if (q->line == lc)
- continue;
- if (currfile != lh->file) {
- currfile = lh->file;
+ if(file != pcfile.value) {
cput(DW_LNS_set_file);
- uleb128put(currfile);
+ uleb128put(pcfile.value);
+ file = pcfile.value;
}
- putpclcdelta(q->pc - pc, lline - llc);
- pc = q->pc;
- lc = q->line;
- llc = lline;
+ putpclcdelta(s->value + pcline.pc - pc, pcline.value - line);
+
+ pc = s->value + pcline.pc;
+ line = pcline.value;
+ if(pcfile.nextpc < pcline.nextpc)
+ epc = pcfile.nextpc;
+ else
+ epc = pcline.nextpc;
+ epc += s->value;
}
da = 0;
@@ -1892,11 +1638,11 @@ writelines(void)
memset(varhash, 0, sizeof varhash);
for(a = s->autom; a; a = a->link) {
switch (a->type) {
- case D_AUTO:
+ case A_AUTO:
dt = DW_ABRV_AUTO;
offs = a->aoffset - PtrSize;
break;
- case D_PARAM:
+ case A_PARAM:
dt = DW_ABRV_PARAM;
offs = a->aoffset;
break;
@@ -1970,12 +1716,12 @@ putpccfadelta(vlong deltapc, vlong cfa)
static void
writeframes(void)
{
- Prog *p, *q;
- Sym *s;
- vlong fdeo, fdesize, pad, cfa, pc;
+ LSym *s;
+ vlong fdeo, fdesize, pad;
+ Pciter pcsp;
if(framesec == S)
- framesec = lookup(".dwarfframe", 0);
+ framesec = linklookup(ctxt, ".dwarfframe", 0);
framesec->nr = 0;
frameo = cpos();
@@ -2003,9 +1749,9 @@ writeframes(void)
}
strnput("", pad);
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- s = cursym;
- if(s->text == nil)
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
+ s = ctxt->cursym;
+ if(s->pcln == nil)
continue;
fdeo = cpos();
@@ -2015,17 +1761,8 @@ writeframes(void)
addrput(0); // initial location
addrput(0); // address range
- cfa = PtrSize; // CFA starts at sp+PtrSize
- p = s->text;
- pc = p->pc;
-
- for(q = p; q->link != P; q = q->link) {
- if (q->spadj == 0)
- continue;
- cfa += q->spadj;
- putpccfadelta(q->link->pc - pc, cfa);
- pc = q->link->pc;
- }
+ for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp))
+ putpccfadelta(pcsp.nextpc - pcsp.pc, PtrSize + pcsp.value);
fdesize = cpos() - fdeo - 4; // exclude the length field.
pad = rnd(fdesize, PtrSize) - fdesize;
@@ -2041,7 +1778,7 @@ writeframes(void)
}
else {
LPUT(0);
- addrput(p->pc);
+ addrput(s->value);
}
addrput(s->size);
cseek(fdeo + 4 + fdesize);
@@ -2067,11 +1804,11 @@ writeinfo(void)
fwdcount = 0;
if (infosec == S)
- infosec = lookup(".dwarfinfo", 0);
+ infosec = linklookup(ctxt, ".dwarfinfo", 0);
infosec->nr = 0;
if(arangessec == S)
- arangessec = lookup(".dwarfaranges", 0);
+ arangessec = linklookup(ctxt, ".dwarfaranges", 0);
arangessec->nr = 0;
for (compunit = dwroot.child; compunit; compunit = compunit->link) {
@@ -2204,7 +1941,7 @@ writearanges(void)
strnput("", headersize - (4+2+4+1+1)); // align to PtrSize
if(linkmode == LinkExternal)
- adddwarfrel(arangessec, (Sym*)b->data, sectionstart, PtrSize, b->value-((Sym*)b->data)->value);
+ adddwarfrel(arangessec, (LSym*)b->data, sectionstart, PtrSize, b->value-((LSym*)b->data)->value);
else
addrput(b->value);
@@ -2239,7 +1976,7 @@ align(vlong size)
}
static vlong
-writedwarfreloc(Sym* s)
+writedwarfreloc(LSym* s)
{
int i;
vlong start;
@@ -2408,7 +2145,7 @@ enum
vlong elfstrdbg[NElfStrDbg];
void
-dwarfaddshstrings(Sym *shstrtab)
+dwarfaddshstrings(LSym *shstrtab)
{
if(debug['w']) // disable dwarf
return;
@@ -2438,16 +2175,16 @@ dwarfaddshstrings(Sym *shstrtab)
elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rel.debug_frame");
}
- infosym = lookup(".debug_info", 0);
+ infosym = linklookup(ctxt, ".debug_info", 0);
infosym->hide = 1;
- abbrevsym = lookup(".debug_abbrev", 0);
+ abbrevsym = linklookup(ctxt, ".debug_abbrev", 0);
abbrevsym->hide = 1;
- linesym = lookup(".debug_line", 0);
+ linesym = linklookup(ctxt, ".debug_line", 0);
linesym->hide = 1;
- framesym = lookup(".debug_frame", 0);
+ framesym = linklookup(ctxt, ".debug_frame", 0);
framesym->hide = 1;
}
}
@@ -2616,31 +2353,37 @@ dwarfaddmachoheaders(void)
ms = newMachoSeg("__DWARF", nsect);
ms->fileoffset = fakestart;
ms->filesize = abbrevo-fakestart;
+ ms->vaddr = ms->fileoffset + segdata.vaddr - segdata.fileoff;
msect = newMachoSect(ms, "__debug_abbrev", "__DWARF");
msect->off = abbrevo;
msect->size = abbrevsize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
msect = newMachoSect(ms, "__debug_line", "__DWARF");
msect->off = lineo;
msect->size = linesize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
msect = newMachoSect(ms, "__debug_frame", "__DWARF");
msect->off = frameo;
msect->size = framesize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
msect = newMachoSect(ms, "__debug_info", "__DWARF");
msect->off = infoo;
msect->size = infosize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
if (pubnamessize > 0) {
msect = newMachoSect(ms, "__debug_pubnames", "__DWARF");
msect->off = pubnameso;
msect->size = pubnamessize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
}
@@ -2648,6 +2391,7 @@ dwarfaddmachoheaders(void)
msect = newMachoSect(ms, "__debug_pubtypes", "__DWARF");
msect->off = pubtypeso;
msect->size = pubtypessize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
}
@@ -2655,6 +2399,7 @@ dwarfaddmachoheaders(void)
msect = newMachoSect(ms, "__debug_aranges", "__DWARF");
msect->off = arangeso;
msect->size = arangessize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
}
@@ -2663,6 +2408,7 @@ dwarfaddmachoheaders(void)
msect = newMachoSect(ms, "__debug_gdb_scripts", "__DWARF");
msect->off = gdbscripto;
msect->size = gdbscriptsize;
+ msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
ms->filesize += msect->size;
}
}
diff --git a/src/cmd/ld/dwarf.h b/src/cmd/ld/dwarf.h
index f0df2f9b1..32db36dcd 100644
--- a/src/cmd/ld/dwarf.h
+++ b/src/cmd/ld/dwarf.h
@@ -3,12 +3,6 @@
// license that can be found in the LICENSE file.
/*
- * Register 'f' symbol file fragments. Doing this while parsing the
- * .6 input saves a pass over the symbol table later.
- */
-void dwarfaddfrag(int n, char* frag);
-
-/*
* Emit debug_abbrevs, debug_info and debug_line sections to current
* offset in cout.
*/
@@ -19,7 +13,7 @@ void dwarfemitdebugsections(void);
* s[ection]h[eader]str[ing]tab. Prerequisite for
* dwarfaddelfheaders().
*/
-void dwarfaddshstrings(Sym *shstrtab);
+void dwarfaddshstrings(LSym *shstrtab);
/*
* Add section headers pointing to the sections emitted in
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c
index 6b3638ec5..0555cf46a 100644
--- a/src/cmd/ld/elf.c
+++ b/src/cmd/ld/elf.c
@@ -55,8 +55,8 @@ elfinit(void)
// 32-bit architectures
case '5':
- // we only use EABI on linux/arm
- if(HEADTYPE == Hlinux)
+ // we use EABI on both linux/arm and freebsd/arm.
+ if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd)
hdr.flags = 0x5000002; // has entry point, Version5 EABI
// fallthrough
default:
@@ -287,35 +287,35 @@ elfhash(uchar *name)
}
void
-elfwritedynent(Sym *s, int tag, uint64 val)
+elfwritedynent(LSym *s, int tag, uint64 val)
{
if(elf64) {
- adduint64(s, tag);
- adduint64(s, val);
+ adduint64(ctxt, s, tag);
+ adduint64(ctxt, s, val);
} else {
- adduint32(s, tag);
- adduint32(s, val);
+ adduint32(ctxt, s, tag);
+ adduint32(ctxt, s, val);
}
}
void
-elfwritedynentsym(Sym *s, int tag, Sym *t)
+elfwritedynentsym(LSym *s, int tag, LSym *t)
{
if(elf64)
- adduint64(s, tag);
+ adduint64(ctxt, s, tag);
else
- adduint32(s, tag);
- addaddr(s, t);
+ adduint32(ctxt, s, tag);
+ addaddr(ctxt, s, t);
}
void
-elfwritedynentsymsize(Sym *s, int tag, Sym *t)
+elfwritedynentsymsize(LSym *s, int tag, LSym *t)
{
if(elf64)
- adduint64(s, tag);
+ adduint64(ctxt, s, tag);
else
- adduint32(s, tag);
- addsize(s, t);
+ adduint32(ctxt, s, tag);
+ addsize(ctxt, s, t);
}
int
@@ -355,7 +355,7 @@ elfnote(ElfShdr *sh, uint64 startva, uint64 resoff, int sz)
sh->addralign = 4;
sh->addr = startva + resoff - n;
sh->off = resoff - n;
- sh->size = n;
+ sh->size = n - resoff % 4;
return n;
}
@@ -388,7 +388,7 @@ elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
{
int n;
- n = ELF_NOTE_NETBSD_NAMESZ + ELF_NOTE_NETBSD_DESCSZ + 1;
+ n = rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + rnd(ELF_NOTE_NETBSD_DESCSZ, 4);
return elfnote(sh, startva, resoff, n);
}
@@ -561,7 +561,7 @@ haveaux:
void
elfdynhash(void)
{
- Sym *s, *sy, *dynstr;
+ LSym *s, *sy, *dynstr;
int i, j, nbucket, b, nfile;
uint32 hc, *chain, *buckets;
int nsym;
@@ -575,7 +575,7 @@ elfdynhash(void)
return;
nsym = nelfsym;
- s = lookup(".hash", 0);
+ s = linklookup(ctxt, ".hash", 0);
s->type = SELFROSECT;
s->reachable = 1;
@@ -591,14 +591,14 @@ elfdynhash(void)
chain = malloc(nsym * sizeof chain[0]);
buckets = malloc(nbucket * sizeof buckets[0]);
if(need == nil || chain == nil || buckets == nil) {
- cursym = nil;
+ ctxt->cursym = nil;
diag("out of memory");
errorexit();
}
memset(need, 0, nsym * sizeof need[0]);
memset(chain, 0, nsym * sizeof chain[0]);
memset(buckets, 0, nbucket * sizeof buckets[0]);
- for(sy=allsym; sy!=S; sy=sy->allsym) {
+ for(sy=ctxt->allsym; sy!=S; sy=sy->allsym) {
if (sy->dynid <= 0)
continue;
@@ -613,70 +613,87 @@ elfdynhash(void)
buckets[b] = sy->dynid;
}
- adduint32(s, nbucket);
- adduint32(s, nsym);
+ adduint32(ctxt, s, nbucket);
+ adduint32(ctxt, s, nsym);
for(i = 0; i<nbucket; i++)
- adduint32(s, buckets[i]);
+ adduint32(ctxt, s, buckets[i]);
for(i = 0; i<nsym; i++)
- adduint32(s, chain[i]);
+ adduint32(ctxt, s, chain[i]);
free(chain);
free(buckets);
// version symbols
- dynstr = lookup(".dynstr", 0);
- s = lookup(".gnu.version_r", 0);
+ dynstr = linklookup(ctxt, ".dynstr", 0);
+ s = linklookup(ctxt, ".gnu.version_r", 0);
i = 2;
nfile = 0;
for(l=needlib; l; l=l->next) {
nfile++;
// header
- adduint16(s, 1); // table version
+ adduint16(ctxt, s, 1); // table version
j = 0;
for(x=l->aux; x; x=x->next)
j++;
- adduint16(s, j); // aux count
- adduint32(s, addstring(dynstr, l->file)); // file string offset
- adduint32(s, 16); // offset from header to first aux
+ adduint16(ctxt, s, j); // aux count
+ adduint32(ctxt, s, addstring(dynstr, l->file)); // file string offset
+ adduint32(ctxt, s, 16); // offset from header to first aux
if(l->next)
- adduint32(s, 16+j*16); // offset from this header to next
+ adduint32(ctxt, s, 16+j*16); // offset from this header to next
else
- adduint32(s, 0);
+ adduint32(ctxt, s, 0);
for(x=l->aux; x; x=x->next) {
x->num = i++;
// aux struct
- adduint32(s, elfhash((uchar*)x->vers)); // hash
- adduint16(s, 0); // flags
- adduint16(s, x->num); // other - index we refer to this by
- adduint32(s, addstring(dynstr, x->vers)); // version string offset
+ adduint32(ctxt, s, elfhash((uchar*)x->vers)); // hash
+ adduint16(ctxt, s, 0); // flags
+ adduint16(ctxt, s, x->num); // other - index we refer to this by
+ adduint32(ctxt, s, addstring(dynstr, x->vers)); // version string offset
if(x->next)
- adduint32(s, 16); // offset from this aux to next
+ adduint32(ctxt, s, 16); // offset from this aux to next
else
- adduint32(s, 0);
+ adduint32(ctxt, s, 0);
}
}
// version references
- s = lookup(".gnu.version", 0);
+ s = linklookup(ctxt, ".gnu.version", 0);
for(i=0; i<nsym; i++) {
if(i == 0)
- adduint16(s, 0); // first entry - no symbol
+ adduint16(ctxt, s, 0); // first entry - no symbol
else if(need[i] == nil)
- adduint16(s, 1); // global
+ adduint16(ctxt, s, 1); // global
else
- adduint16(s, need[i]->num);
+ adduint16(ctxt, s, need[i]->num);
}
free(need);
- s = lookup(".dynamic", 0);
+ s = linklookup(ctxt, ".dynamic", 0);
elfverneed = nfile;
if(elfverneed) {
- elfwritedynentsym(s, DT_VERNEED, lookup(".gnu.version_r", 0));
+ elfwritedynentsym(s, DT_VERNEED, linklookup(ctxt, ".gnu.version_r", 0));
elfwritedynent(s, DT_VERNEEDNUM, nfile);
- elfwritedynentsym(s, DT_VERSYM, lookup(".gnu.version", 0));
+ elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
+ }
+
+ if(thechar == '6') {
+ sy = linklookup(ctxt, ".rela.plt", 0);
+ if(sy->size > 0) {
+ elfwritedynent(s, DT_PLTREL, DT_RELA);
+ elfwritedynentsymsize(s, DT_PLTRELSZ, sy);
+ elfwritedynentsym(s, DT_JMPREL, sy);
+ }
+ } else {
+ sy = linklookup(ctxt, ".rel.plt", 0);
+ if(sy->size > 0) {
+ elfwritedynent(s, DT_PLTREL, DT_REL);
+ elfwritedynentsymsize(s, DT_PLTRELSZ, sy);
+ elfwritedynentsym(s, DT_JMPREL, sy);
+ }
}
+
elfwritedynent(s, DT_NULL, 0);
}
@@ -797,19 +814,19 @@ elfshreloc(Section *sect)
snprint(buf, sizeof buf, "%s%s", prefix, sect->name);
sh = elfshname(buf);
sh->type = typ;
- sh->entsize = PtrSize*(2+(typ==SHT_RELA));
+ sh->entsize = RegSize*(2+(typ==SHT_RELA));
sh->link = elfshname(".symtab")->shnum;
sh->info = sect->elfsect->shnum;
sh->off = sect->reloff;
sh->size = sect->rellen;
- sh->addralign = PtrSize;
+ sh->addralign = RegSize;
return sh;
}
void
-elfrelocsect(Section *sect, Sym *first)
+elfrelocsect(Section *sect, LSym *first)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr;
Reloc *r;
@@ -834,7 +851,7 @@ elfrelocsect(Section *sect, Sym *first)
continue;
if(sym->value >= eaddr)
break;
- cursym = sym;
+ ctxt->cursym = sym;
for(r = sym->r; r < sym->r+sym->nr; r++) {
if(r->done)
@@ -861,7 +878,7 @@ elfemitreloc(void)
while(cpos()&7)
cput(0);
- elfrelocsect(segtext.sect, textp);
+ elfrelocsect(segtext.sect, ctxt->textp);
for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
elfrelocsect(sect, datap);
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
@@ -873,13 +890,13 @@ elfemitreloc(void)
void
doelf(void)
{
- Sym *s, *shstrtab, *dynstr;
+ LSym *s, *shstrtab, *dynstr;
if(!iself)
return;
/* predefine strings we need for section headers */
- shstrtab = lookup(".shstrtab", 0);
+ shstrtab = linklookup(ctxt, ".shstrtab", 0);
shstrtab->type = SELFROSECT;
shstrtab->reachable = 1;
@@ -969,7 +986,7 @@ doelf(void)
addstring(shstrtab, ".gnu.version_r");
/* dynamic symbol table - first entry all zeros */
- s = lookup(".dynsym", 0);
+ s = linklookup(ctxt, ".dynsym", 0);
s->type = SELFROSECT;
s->reachable = 1;
if(thechar == '6')
@@ -978,7 +995,7 @@ doelf(void)
s->size += ELF32SYMSIZE;
/* dynamic string table */
- s = lookup(".dynstr", 0);
+ s = linklookup(ctxt, ".dynstr", 0);
s->type = SELFROSECT;
s->reachable = 1;
if(s->size == 0)
@@ -987,87 +1004,81 @@ doelf(void)
/* relocation table */
if(thechar == '6')
- s = lookup(".rela", 0);
+ s = linklookup(ctxt, ".rela", 0);
else
- s = lookup(".rel", 0);
+ s = linklookup(ctxt, ".rel", 0);
s->reachable = 1;
s->type = SELFROSECT;
/* global offset table */
- s = lookup(".got", 0);
+ s = linklookup(ctxt, ".got", 0);
s->reachable = 1;
s->type = SELFSECT; // writable
/* hash */
- s = lookup(".hash", 0);
+ s = linklookup(ctxt, ".hash", 0);
s->reachable = 1;
s->type = SELFROSECT;
- s = lookup(".got.plt", 0);
+ s = linklookup(ctxt, ".got.plt", 0);
s->reachable = 1;
s->type = SELFSECT; // writable
- s = lookup(".plt", 0);
+ s = linklookup(ctxt, ".plt", 0);
s->reachable = 1;
s->type = SELFRXSECT;
elfsetupplt();
if(thechar == '6')
- s = lookup(".rela.plt", 0);
+ s = linklookup(ctxt, ".rela.plt", 0);
else
- s = lookup(".rel.plt", 0);
+ s = linklookup(ctxt, ".rel.plt", 0);
s->reachable = 1;
s->type = SELFROSECT;
- s = lookup(".gnu.version", 0);
+ s = linklookup(ctxt, ".gnu.version", 0);
s->reachable = 1;
s->type = SELFROSECT;
- s = lookup(".gnu.version_r", 0);
+ s = linklookup(ctxt, ".gnu.version_r", 0);
s->reachable = 1;
s->type = SELFROSECT;
/* define dynamic elf table */
- s = lookup(".dynamic", 0);
+ s = linklookup(ctxt, ".dynamic", 0);
s->reachable = 1;
s->type = SELFSECT; // writable
/*
* .dynamic table
*/
- elfwritedynentsym(s, DT_HASH, lookup(".hash", 0));
- elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0));
+ elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
+ elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
if(thechar == '6')
elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
else
elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
- elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0));
- elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0));
+ elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
+ elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0));
if(thechar == '6') {
- elfwritedynentsym(s, DT_RELA, lookup(".rela", 0));
- elfwritedynentsymsize(s, DT_RELASZ, lookup(".rela", 0));
+ elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0));
+ elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
} else {
- elfwritedynentsym(s, DT_REL, lookup(".rel", 0));
- elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0));
+ elfwritedynentsym(s, DT_REL, linklookup(ctxt, ".rel", 0));
+ elfwritedynentsymsize(s, DT_RELSZ, linklookup(ctxt, ".rel", 0));
elfwritedynent(s, DT_RELENT, ELF32RELSIZE);
}
if(rpath)
elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath));
- elfwritedynentsym(s, DT_PLTGOT, lookup(".got.plt", 0));
+ elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0));
- if(thechar == '6') {
- elfwritedynent(s, DT_PLTREL, DT_RELA);
- elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rela.plt", 0));
- elfwritedynentsym(s, DT_JMPREL, lookup(".rela.plt", 0));
- } else {
- elfwritedynent(s, DT_PLTREL, DT_REL);
- elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0));
- elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0));
- }
-
+ // Solaris dynamic linker can't handle an empty .rela.plt if
+ // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
+ // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
+ // size of .rel(a).plt section.
elfwritedynent(s, DT_DEBUG, 0);
// Do not write DT_NULL. elfdynhash will finish it.
@@ -1075,7 +1086,7 @@ doelf(void)
}
void
-shsym(ElfShdr *sh, Sym *s)
+shsym(ElfShdr *sh, LSym *s)
{
vlong addr;
addr = symaddr(s);
@@ -1152,7 +1163,7 @@ asmbelf(vlong symo)
/* program header info */
pph = newElfPhdr();
pph->type = PT_PHDR;
- pph->flags = PF_R + PF_X;
+ pph->flags = PF_R;
pph->off = eh->ehsize;
pph->vaddr = INITTEXT - HEADR + pph->off;
pph->paddr = INITTEXT - HEADR + pph->off;
@@ -1161,13 +1172,16 @@ asmbelf(vlong symo)
/*
* PHDR must be in a loaded segment. Adjust the text
* segment boundaries downwards to include it.
+ * Except on NaCl where it must not be loaded.
*/
- o = segtext.vaddr - pph->vaddr;
- segtext.vaddr -= o;
- segtext.len += o;
- o = segtext.fileoff - pph->off;
- segtext.fileoff -= o;
- segtext.filelen += o;
+ if(HEADTYPE != Hnacl) {
+ o = segtext.vaddr - pph->vaddr;
+ segtext.vaddr -= o;
+ segtext.len += o;
+ o = segtext.fileoff - pph->off;
+ segtext.fileoff -= o;
+ segtext.filelen += o;
+ }
if(!debug['d']) {
/* interpreter */
@@ -1192,6 +1206,9 @@ asmbelf(vlong symo)
case Hdragonfly:
interpreter = dragonflydynld;
break;
+ case Hsolaris:
+ interpreter = solarisdynld;
+ break;
}
}
resoff -= elfinterp(sh, startva, resoff, interpreter);
@@ -1247,20 +1264,20 @@ asmbelf(vlong symo)
sh = elfshname(".dynsym");
sh->type = SHT_DYNSYM;
sh->flags = SHF_ALLOC;
- if(PtrSize == 8)
+ if(elf64)
sh->entsize = ELF64SYMSIZE;
else
sh->entsize = ELF32SYMSIZE;
- sh->addralign = PtrSize;
+ sh->addralign = RegSize;
sh->link = elfshname(".dynstr")->shnum;
// sh->info = index of first non-local symbol (number of local symbols)
- shsym(sh, lookup(".dynsym", 0));
+ shsym(sh, linklookup(ctxt, ".dynsym", 0));
sh = elfshname(".dynstr");
sh->type = SHT_STRTAB;
sh->flags = SHF_ALLOC;
sh->addralign = 1;
- shsym(sh, lookup(".dynstr", 0));
+ shsym(sh, linklookup(ctxt, ".dynstr", 0));
if(elfverneed) {
sh = elfshname(".gnu.version");
@@ -1269,15 +1286,15 @@ asmbelf(vlong symo)
sh->addralign = 2;
sh->link = elfshname(".dynsym")->shnum;
sh->entsize = 2;
- shsym(sh, lookup(".gnu.version", 0));
+ shsym(sh, linklookup(ctxt, ".gnu.version", 0));
sh = elfshname(".gnu.version_r");
sh->type = SHT_GNU_VERNEED;
sh->flags = SHF_ALLOC;
- sh->addralign = PtrSize;
+ sh->addralign = RegSize;
sh->info = elfverneed;
sh->link = elfshname(".dynstr")->shnum;
- shsym(sh, lookup(".gnu.version_r", 0));
+ shsym(sh, linklookup(ctxt, ".gnu.version_r", 0));
}
switch(eh->machine) {
@@ -1286,10 +1303,10 @@ asmbelf(vlong symo)
sh->type = SHT_RELA;
sh->flags = SHF_ALLOC;
sh->entsize = ELF64RELASIZE;
- sh->addralign = PtrSize;
+ sh->addralign = RegSize;
sh->link = elfshname(".dynsym")->shnum;
sh->info = elfshname(".plt")->shnum;
- shsym(sh, lookup(".rela.plt", 0));
+ shsym(sh, linklookup(ctxt, ".rela.plt", 0));
sh = elfshname(".rela");
sh->type = SHT_RELA;
@@ -1297,7 +1314,7 @@ asmbelf(vlong symo)
sh->entsize = ELF64RELASIZE;
sh->addralign = 8;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".rela", 0));
+ shsym(sh, linklookup(ctxt, ".rela", 0));
break;
default:
@@ -1306,7 +1323,7 @@ asmbelf(vlong symo)
sh->flags = SHF_ALLOC;
sh->entsize = ELF32RELSIZE;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".rel.plt", 0));
+ shsym(sh, linklookup(ctxt, ".rel.plt", 0));
sh = elfshname(".rel");
sh->type = SHT_REL;
@@ -1314,7 +1331,7 @@ asmbelf(vlong symo)
sh->entsize = ELF32RELSIZE;
sh->addralign = 4;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".rel", 0));
+ shsym(sh, linklookup(ctxt, ".rel", 0));
break;
}
@@ -1326,38 +1343,38 @@ asmbelf(vlong symo)
else
sh->entsize = 4;
sh->addralign = 4;
- shsym(sh, lookup(".plt", 0));
+ shsym(sh, linklookup(ctxt, ".plt", 0));
sh = elfshname(".got");
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC+SHF_WRITE;
- sh->entsize = PtrSize;
- sh->addralign = PtrSize;
- shsym(sh, lookup(".got", 0));
+ sh->entsize = RegSize;
+ sh->addralign = RegSize;
+ shsym(sh, linklookup(ctxt, ".got", 0));
sh = elfshname(".got.plt");
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC+SHF_WRITE;
- sh->entsize = PtrSize;
- sh->addralign = PtrSize;
- shsym(sh, lookup(".got.plt", 0));
+ sh->entsize = RegSize;
+ sh->addralign = RegSize;
+ shsym(sh, linklookup(ctxt, ".got.plt", 0));
sh = elfshname(".hash");
sh->type = SHT_HASH;
sh->flags = SHF_ALLOC;
sh->entsize = 4;
- sh->addralign = PtrSize;
+ sh->addralign = RegSize;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".hash", 0));
+ shsym(sh, linklookup(ctxt, ".hash", 0));
/* sh and PT_DYNAMIC for .dynamic section */
sh = elfshname(".dynamic");
sh->type = SHT_DYNAMIC;
sh->flags = SHF_ALLOC+SHF_WRITE;
- sh->entsize = 2*PtrSize;
- sh->addralign = PtrSize;
+ sh->entsize = 2*RegSize;
+ sh->addralign = RegSize;
sh->link = elfshname(".dynstr")->shnum;
- shsym(sh, lookup(".dynamic", 0));
+ shsym(sh, linklookup(ctxt, ".dynamic", 0));
ph = newElfPhdr();
ph->type = PT_DYNAMIC;
ph->flags = PF_R + PF_W;
@@ -1369,12 +1386,12 @@ asmbelf(vlong symo)
// Do not emit PT_TLS for OpenBSD since ld.so(1) does
// not currently support it. This is handled
// appropriately in runtime/cgo.
- if(tlsoffset != 0 && HEADTYPE != Hopenbsd) {
+ if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd) {
ph = newElfPhdr();
ph->type = PT_TLS;
ph->flags = PF_R;
- ph->memsz = -tlsoffset;
- ph->align = PtrSize;
+ ph->memsz = -ctxt->tlsoffset;
+ ph->align = RegSize;
}
}
@@ -1382,19 +1399,19 @@ asmbelf(vlong symo)
ph = newElfPhdr();
ph->type = PT_GNU_STACK;
ph->flags = PF_W+PF_R;
- ph->align = PtrSize;
+ ph->align = RegSize;
ph = newElfPhdr();
ph->type = PT_PAX_FLAGS;
ph->flags = 0x2a00; // mprotect, randexec, emutramp disabled
- ph->align = PtrSize;
+ ph->align = RegSize;
}
elfobj:
sh = elfshname(".shstrtab");
sh->type = SHT_STRTAB;
sh->addralign = 1;
- shsym(sh, lookup(".shstrtab", 0));
+ shsym(sh, linklookup(ctxt, ".shstrtab", 0));
eh->shstrndx = sh->shnum;
// put these sections early in the list
@@ -1429,8 +1446,8 @@ elfobj:
if(linkmode == LinkInternal && !debug['d'] && HEADTYPE != Hopenbsd) {
sh = elfshname(".tbss");
sh->type = SHT_NOBITS;
- sh->addralign = PtrSize;
- sh->size = -tlsoffset;
+ sh->addralign = RegSize;
+ sh->size = -ctxt->tlsoffset;
sh->flags = SHF_ALLOC | SHF_TLS | SHF_WRITE;
}
@@ -1439,8 +1456,8 @@ elfobj:
sh->type = SHT_SYMTAB;
sh->off = symo;
sh->size = symsize;
- sh->addralign = PtrSize;
- sh->entsize = 8+2*PtrSize;
+ sh->addralign = RegSize;
+ sh->entsize = 8+2*RegSize;
sh->link = elfshname(".strtab")->shnum;
sh->info = elfglobalsymndx;
@@ -1466,7 +1483,7 @@ elfobj:
eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
else if(HEADTYPE == Hdragonfly)
eh->ident[EI_OSABI] = ELFOSABI_NONE;
- if(PtrSize == 8)
+ if(elf64)
eh->ident[EI_CLASS] = ELFCLASS64;
else
eh->ident[EI_CLASS] = ELFCLASS32;
@@ -1504,5 +1521,5 @@ elfobj:
a += elfwritebuildinfo();
}
if(a > ELFRESERVE)
- diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
+ diag("ELFRESERVE too small: %lld > %d", a, ELFRESERVE);
}
diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h
index 5b2ff041a..e84d996f2 100644
--- a/src/cmd/ld/elf.h
+++ b/src/cmd/ld/elf.h
@@ -858,7 +858,7 @@ struct Elf64_Shdr {
Elf64_Xword entsize; /* Size of each entry in section. */
int shnum; /* section number, not stored on disk */
- Sym* secsym; /* section symbol, if needed; not on disk */
+ LSym* secsym; /* section symbol, if needed; not on disk */
};
/*
@@ -968,9 +968,9 @@ ElfPhdr *newElfPhdr(void);
uint32 elfwritehdr(void);
uint32 elfwritephdrs(void);
uint32 elfwriteshdrs(void);
-void elfwritedynent(Sym*, int, uint64);
-void elfwritedynentsym(Sym*, int, Sym*);
-void elfwritedynentsymsize(Sym*, int, Sym*);
+void elfwritedynent(LSym*, int, uint64);
+void elfwritedynentsym(LSym*, int, LSym*);
+void elfwritedynentsymsize(LSym*, int, LSym*);
uint32 elfhash(uchar*);
uint64 startelf(void);
uint64 endelf(void);
@@ -994,13 +994,13 @@ ElfShdr* elfshalloc(Section*);
ElfShdr* elfshname(char*);
ElfShdr* elfshreloc(Section*);
void elfsetstring(char*, int);
-void elfaddverneed(Sym*);
+void elfaddverneed(LSym*);
void elfemitreloc(void);
-void shsym(ElfShdr*, Sym*);
+void shsym(ElfShdr*, LSym*);
void phsh(ElfPhdr*, ElfShdr*);
void doelf(void);
void elfsetupplt(void);
-void dwarfaddshstrings(Sym*);
+void dwarfaddshstrings(LSym*);
void dwarfaddelfsectionsyms(void);
void dwarfaddelfheaders(void);
void asmbelf(vlong symo);
@@ -1010,6 +1010,7 @@ extern char freebsddynld[];
extern char netbsddynld[];
extern char openbsddynld[];
extern char dragonflydynld[];
+extern char solarisdynld[];
int elfreloc1(Reloc*, vlong sectoff);
void putelfsectionsyms(void);
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
index 39ffa3d87..9c296b740 100644
--- a/src/cmd/ld/go.c
+++ b/src/cmd/ld/go.c
@@ -151,28 +151,11 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence)
}
loadpkgdata(filename, pkg, p0, p1 - p0);
}
-
- // The __.PKGDEF archive summary has no local types.
+
+ // __.PKGDEF has no cgo section - those are in the C compiler-generated object files.
if(whence == Pkgdef)
return;
- // local types begin where exports end.
- // skip rest of line after $$ we found above
- p0 = p1 + 3;
- while(*p0 != '\n' && *p0 != '\0')
- p0++;
-
- // local types end at next \n$$.
- p1 = strstr(p0, "\n$$");
- if(p1 == nil) {
- fprint(2, "%s: cannot find end of local types in %s\n", argv0, filename);
- if(debug['u'])
- errorexit();
- return;
- }
-
- loadpkgdata(filename, pkg, p0, p1 - p0);
-
// look for cgo section
p0 = strstr(p1, "\n$$ // cgo");
if(p0 != nil) {
@@ -228,39 +211,6 @@ loadpkgdata(char *file, char *pkg, char *data, int len)
free(file);
}
-// replace all "". with pkg.
-char*
-expandpkg(char *t0, char *pkg)
-{
- int n;
- char *p;
- char *w, *w0, *t;
-
- n = 0;
- for(p=t0; (p=strstr(p, "\"\".")) != nil; p+=3)
- n++;
-
- if(n == 0)
- return estrdup(t0);
-
- // use malloc, not mal, so that caller can free
- w0 = malloc(strlen(t0) + strlen(pkg)*n);
- if(w0 == nil) {
- diag("out of memory");
- errorexit();
- }
- w = w0;
- for(p=t=t0; (p=strstr(p, "\"\".")) != nil; p=t) {
- memmove(w, t, p - t);
- w += p-t;
- strcpy(w, pkg);
- w += strlen(pkg);
- t = p+2;
- }
- strcpy(w, t);
- return w0;
-}
-
static int
parsepkgdata(char *file, char *pkg, char **pp, char *ep, char **prefixp, char **namep, char **defp)
{
@@ -413,7 +363,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
char *pend, *next, *p0, *q;
char *f[10], *local, *remote, *lib;
int nf;
- Sym *s;
+ LSym *s;
USED(file);
pend = p + n;
@@ -459,7 +409,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
q = strchr(remote, '#');
if(q)
*q++ = '\0';
- s = lookup(local, 0);
+ s = linklookup(ctxt, local, 0);
if(local != f[1])
free(local);
if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) {
@@ -477,7 +427,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
if(nf != 2)
goto err;
local = f[1];
- s = lookup(local, 0);
+ s = linklookup(ctxt, local, 0);
s->type = SHOSTOBJ;
s->size = 0;
continue;
@@ -496,9 +446,9 @@ loadcgo(char *file, char *pkg, char *p, int n)
else
remote = local;
local = expandpkg(local, pkg);
- s = lookup(local, 0);
+ s = linklookup(ctxt, local, 0);
- if(flag_shared && s == lookup("main", 0))
+ if(flag_shared && s == linklookup(ctxt, "main", 0))
continue;
// export overrides import, for openbsd/cgo.
@@ -562,11 +512,11 @@ err:
nerrors++;
}
-static Sym *markq;
-static Sym *emarkq;
+static LSym *markq;
+static LSym *emarkq;
static void
-mark1(Sym *s, Sym *parent)
+mark1(LSym *s, LSym *parent)
{
if(s == S || s->reachable)
return;
@@ -582,7 +532,7 @@ mark1(Sym *s, Sym *parent)
}
void
-mark(Sym *s)
+mark(LSym *s)
{
mark1(s, nil);
}
@@ -591,23 +541,22 @@ static void
markflood(void)
{
Auto *a;
- Prog *p;
- Sym *s;
+ LSym *s;
int i;
for(s=markq; s!=S; s=s->queue) {
- if(s->text) {
+ if(s->type == STEXT) {
if(debug['v'] > 1)
Bprint(&bso, "marktext %s\n", s->name);
for(a=s->autom; a; a=a->link)
mark1(a->gotype, s);
- for(p=s->text; p != P; p=p->link) {
- mark1(p->from.sym, s);
- mark1(p->to.sym, s);
- }
}
for(i=0; i<s->nr; i++)
mark1(s->r[i].sym, s);
+ if(s->pcln) {
+ for(i=0; i<s->pcln->nfuncdata; i++)
+ mark1(s->pcln->funcdata[i], s);
+ }
mark1(s->gotype, s);
mark1(s->sub, s);
mark1(s->outer, s);
@@ -639,51 +588,19 @@ markextra[] =
"_modu",
};
-static int
-isz(Auto *a)
-{
- for(; a; a=a->link)
- if(a->type == D_FILE || a->type == D_FILE1)
- return 1;
- return 0;
-}
-
-static void
-addz(Sym *s, Auto *z)
-{
- Auto *a, *last;
-
- // strip out non-z
- last = nil;
- for(a = z; a != nil; a = a->link) {
- if(a->type == D_FILE || a->type == D_FILE1) {
- if(last == nil)
- z = a;
- else
- last->link = a;
- last = a;
- }
- }
- if(last) {
- last->link = s->autom;
- s->autom = z;
- }
-}
-
void
deadcode(void)
{
int i;
- Sym *s, *last, *p;
- Auto *z;
+ LSym *s, *last, *p;
Fmt fmt;
if(debug['v'])
Bprint(&bso, "%5.2f deadcode\n", cputime());
- mark(lookup(INITENTRY, 0));
+ mark(linklookup(ctxt, INITENTRY, 0));
for(i=0; i<nelem(markextra); i++)
- mark(lookup(markextra[i], 0));
+ mark(linklookup(ctxt, markextra[i], 0));
for(i=0; i<ndynexp; i++)
mark(dynexp[i]);
@@ -691,37 +608,29 @@ deadcode(void)
markflood();
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "go.typelink.", 12) == 0)
s->reachable = s->nr==1 && s->r[0].sym->reachable;
}
// remove dead text but keep file information (z symbols).
last = nil;
- z = nil;
- for(s = textp; s != nil; s = s->next) {
- if(!s->reachable) {
- if(isz(s->autom))
- z = s->autom;
+ for(s = ctxt->textp; s != nil; s = s->next) {
+ if(!s->reachable)
continue;
- }
+ // NOTE: Removing s from old textp and adding to new, shorter textp.
if(last == nil)
- textp = s;
+ ctxt->textp = s;
else
last->next = s;
last = s;
- if(z != nil) {
- if(!isz(s->autom))
- addz(s, z);
- z = nil;
- }
}
if(last == nil)
- textp = nil;
+ ctxt->textp = nil;
else
last->next = nil;
- for(s = allsym; s != S; s = s->allsym)
+ for(s = ctxt->allsym; s != S; s = s->allsym)
if(strncmp(s->name, "go.weak.", 8) == 0) {
s->special = 1; // do not lay out in data segment
s->reachable = 1;
@@ -730,7 +639,7 @@ deadcode(void)
// record field tracking references
fmtstrinit(&fmt);
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "go.track.", 9) == 0) {
s->special = 1; // do not lay out in data segment
s->hide = 1;
@@ -746,7 +655,7 @@ deadcode(void)
}
if(tracksym == nil)
return;
- s = lookup(tracksym, 0);
+ s = linklookup(ctxt, tracksym, 0);
if(!s->reachable)
return;
addstrdata(tracksym, fmtstrflush(&fmt));
@@ -755,13 +664,13 @@ deadcode(void)
void
doweak(void)
{
- Sym *s, *t;
+ LSym *s, *t;
// resolve weak references only if
// target symbol will be in binary anyway.
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "go.weak.", 8) == 0) {
- t = rlookup(s->name+8, s->version);
+ t = linkrlookup(ctxt, s->name+8, s->version);
if(t && t->type != 0 && t->reachable) {
s->value = t->value;
s->type = t->type;
@@ -784,7 +693,7 @@ addexport(void)
return;
for(i=0; i<ndynexp; i++)
- adddynsym(dynexp[i]);
+ adddynsym(ctxt, dynexp[i]);
}
/* %Z from gc, for quoting import paths */
diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c
index 27041bc47..1d7c4c13e 100644
--- a/src/cmd/ld/ldelf.c
+++ b/src/cmd/ld/ldelf.c
@@ -258,7 +258,7 @@ struct ElfSect
uint64 align;
uint64 entsize;
uchar *base;
- Sym *sym;
+ LSym *sym;
};
struct ElfObj
@@ -301,7 +301,7 @@ struct ElfSym
uchar type;
uchar other;
uint16 shndx;
- Sym* sym;
+ LSym* sym;
};
uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
@@ -312,7 +312,7 @@ static int readsym(ElfObj*, int i, ElfSym*, int);
static int reltype(char*, int, uchar*);
int
-valuecmp(Sym *a, Sym *b)
+valuecmp(LSym *a, LSym *b)
{
if(a->value < b->value)
return -1;
@@ -336,15 +336,15 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
ElfSym sym;
Endian *e;
Reloc *r, *rp;
- Sym *s;
- Sym **symbols;
+ LSym *s;
+ LSym **symbols;
symbols = nil;
if(debug['v'])
Bprint(&bso, "%5.2f ldelf %s\n", cputime(), pn);
- version++;
+ ctxt->version++;
base = Boffset(f);
if(Bread(f, hdrbuf, sizeof hdrbuf) != sizeof hdrbuf)
@@ -529,7 +529,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
goto bad;
name = smprint("%s(%s)", pkg, sect->name);
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
free(name);
switch((int)sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
default:
@@ -601,24 +601,9 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
s->size = sym.size;
s->outer = sect->sym;
if(sect->sym->type == STEXT) {
- Prog *p;
-
- if(s->text != P) {
- if(!s->dupok)
+ if(s->external && !s->dupok)
diag("%s: duplicate definition of %s", pn, s->name);
- } else {
- // build a TEXT instruction with a unique pc
- // just to make the rest of the linker happy.
- p = prg();
- p->as = ATEXT;
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->textflag = 7;
- p->to.type = D_CONST;
- p->link = nil;
- p->pc = pc++;
- s->text = p;
- }
+ s->external = 1;
}
}
@@ -629,16 +614,22 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
if(s == S)
continue;
if(s->sub)
- s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub));
+ s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
if(s->type == STEXT) {
- if(etextp)
- etextp->next = s;
+ if(s->onlist)
+ sysfatal("symbol %s listed multiple times", s->name);
+ s->onlist = 1;
+ if(ctxt->etextp)
+ ctxt->etextp->next = s;
else
- textp = s;
- etextp = s;
+ ctxt->textp = s;
+ ctxt->etextp = s;
for(s = s->sub; s != S; s = s->sub) {
- etextp->next = s;
- etextp = s;
+ if(s->onlist)
+ sysfatal("symbol %s listed multiple times", s->name);
+ s->onlist = 1;
+ ctxt->etextp->next = s;
+ ctxt->etextp = s;
}
}
}
@@ -712,6 +703,9 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
else
diag("invalid rela size %d", rp->siz);
}
+ if(rp->siz == 4)
+ rp->add = (int32)rp->add;
+ //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add);
}
qsort(r, n, sizeof r[0], rbyoff); // just in case
@@ -761,7 +755,7 @@ map(ElfObj *obj, ElfSect *sect)
static int
readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
{
- Sym *s;
+ LSym *s;
if(i >= obj->nsymtab || i < 0) {
werrstr("invalid elf symbol index");
@@ -808,7 +802,7 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
switch(sym->bind) {
case ElfSymBindGlobal:
if(needSym) {
- s = lookup(sym->name, 0);
+ s = linklookup(ctxt, sym->name, 0);
// for global scoped hidden symbols we should insert it into
// symbol hash table, but mark them as hidden.
// __i686.get_pc_thunk.bx is allowed to be duplicated, to
@@ -828,13 +822,13 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
// local names and hidden visiblity global names are unique
// and should only reference by its index, not name, so we
// don't bother to add them into hash table
- s = newsym(sym->name, version);
+ s = linknewsym(ctxt, sym->name, ctxt->version);
s->type |= SHIDDEN;
}
break;
case ElfSymBindWeak:
if(needSym) {
- s = newsym(sym->name, 0);
+ s = linknewsym(ctxt, sym->name, 0);
if(sym->other == 2)
s->type |= SHIDDEN;
}
diff --git a/src/cmd/ld/ldmacho.c b/src/cmd/ld/ldmacho.c
index e0f5405f6..413dedabd 100644
--- a/src/cmd/ld/ldmacho.c
+++ b/src/cmd/ld/ldmacho.c
@@ -102,7 +102,7 @@ struct MachoSect
uint32 flags;
uint32 res1;
uint32 res2;
- Sym *sym;
+ LSym *sym;
MachoRel *rel;
};
@@ -138,7 +138,7 @@ struct MachoSym
uint16 desc;
char kind;
uint64 value;
- Sym *sym;
+ LSym *sym;
};
struct MachoDysymtab
@@ -432,7 +432,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
int64 base;
MachoSect *sect;
MachoRel *rel;
- Sym *s, *s1, *outer;
+ LSym *s, *s1, *outer;
MachoCmd *c;
MachoSymtab *symtab;
MachoDysymtab *dsymtab;
@@ -440,7 +440,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
Reloc *r, *rp;
char *name;
- version++;
+ ctxt->version++;
base = Boffset(f);
if(Bread(f, hdr, sizeof hdr) != sizeof hdr)
goto bad;
@@ -507,6 +507,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
c = nil;
symtab = nil;
dsymtab = nil;
+ USED(dsymtab);
for(i=0; i<ncmd; i++){
ty = e->e32(cmdp);
sz = e->e32(cmdp+4);
@@ -566,7 +567,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
if(strcmp(sect->name, "__eh_frame") == 0)
continue;
name = smprint("%s(%s/%s)", pkg, sect->segname, sect->name);
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
if(s->type != 0) {
werrstr("duplicate %s/%s", sect->segname, sect->name);
goto bad;
@@ -609,8 +610,8 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
name++;
v = 0;
if(!(sym->type&N_EXT))
- v = version;
- s = lookup(name, v);
+ v = ctxt->version;
+ s = linklookup(ctxt, name, v);
if(!(sym->type&N_EXT))
s->dupok = 1;
sym->sym = s;
@@ -640,22 +641,9 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
if(!(s->cgoexport & CgoExportDynamic))
s->dynimplib = nil; // satisfy dynimport
if(outer->type == STEXT) {
- Prog *p;
-
- if(s->text != P)
- diag("%s sym#%d: duplicate definition of %s", pn, i, s->name);
- // build a TEXT instruction with a unique pc
- // just to make the rest of the linker happy.
- // TODO: this is too 6l-specific ?
- p = prg();
- p->as = ATEXT;
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->textflag = 7;
- p->to.type = D_CONST;
- p->link = nil;
- p->pc = pc++;
- s->text = p;
+ if(s->external && !s->dupok)
+ diag("%s: duplicate definition of %s", pn, s->name);
+ s->external = 1;
}
sym->sym = s;
}
@@ -667,7 +655,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
if((s = sect->sym) == S)
continue;
if(s->sub) {
- s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub));
+ s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
// assign sizes, now that we know symbols in sorted order.
for(s1 = s->sub; s1 != S; s1 = s1->sub) {
@@ -678,14 +666,20 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
}
}
if(s->type == STEXT) {
- if(etextp)
- etextp->next = s;
+ if(s->onlist)
+ sysfatal("symbol %s listed multiple times", s->name);
+ s->onlist = 1;
+ if(ctxt->etextp)
+ ctxt->etextp->next = s;
else
- textp = s;
- etextp = s;
+ ctxt->textp = s;
+ ctxt->etextp = s;
for(s1 = s->sub; s1 != S; s1 = s1->sub) {
- etextp->next = s1;
- etextp = s1;
+ if(s1->onlist)
+ sysfatal("symbol %s listed multiple times", s1->name);
+ s1->onlist = 1;
+ ctxt->etextp->next = s1;
+ ctxt->etextp = s1;
}
}
}
@@ -743,7 +737,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
// want to make it pc-relative aka relative to rp->off+4
// but the scatter asks for relative to off = (rel+1)->value - sect->addr.
// adjust rp->add accordingly.
- rp->type = D_PCREL;
+ rp->type = R_PCREL;
rp->add += (rp->off+4) - ((rel+1)->value - sect->addr);
// now consider the desired symbol.
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c
index 6bcda2cb6..f6eda900d 100644
--- a/src/cmd/ld/ldpe.c
+++ b/src/cmd/ld/ldpe.c
@@ -102,14 +102,14 @@ struct PeSym {
uint16 type;
uint8 sclass;
uint8 aux;
- Sym* sym;
+ LSym* sym;
};
struct PeSect {
char* name;
uchar* base;
uint64 size;
- Sym* sym;
+ LSym* sym;
IMAGE_SECTION_HEADER sh;
};
@@ -141,7 +141,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
PeSect *sect, *rsect;
IMAGE_SECTION_HEADER sh;
uchar symbuf[18];
- Sym *s;
+ LSym *s;
Reloc *r, *rp;
PeSym *sym;
@@ -150,7 +150,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn);
sect = nil;
- version++;
+ ctxt->version++;
base = Boffset(f);
obj = mal(sizeof *obj);
@@ -222,7 +222,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
goto bad;
name = smprint("%s(%s)", pkg, sect->name);
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
free(name);
switch(sect->sh.Characteristics&(IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_CNT_INITIALIZED_DATA|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE)) {
@@ -290,18 +290,18 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
case IMAGE_REL_AMD64_REL32:
case IMAGE_REL_AMD64_ADDR32: // R_X86_64_PC32
case IMAGE_REL_AMD64_ADDR32NB:
- rp->type = D_PCREL;
+ rp->type = R_PCREL;
rp->add = (int32)le32(rsect->base+rp->off);
break;
case IMAGE_REL_I386_DIR32NB:
case IMAGE_REL_I386_DIR32:
- rp->type = D_ADDR;
+ rp->type = R_ADDR;
// load addend from image
- rp->add = le32(rsect->base+rp->off);
+ rp->add = (int32)le32(rsect->base+rp->off);
break;
case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
rp->siz = 8;
- rp->type = D_ADDR;
+ rp->type = R_ADDR;
// load addend from image
rp->add = le64(rsect->base+rp->off);
break;
@@ -366,21 +366,9 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
s->size = 4;
s->outer = sect->sym;
if(sect->sym->type == STEXT) {
- Prog *p;
-
- if(s->text != P)
+ if(s->external && !s->dupok)
diag("%s: duplicate definition of %s", pn, s->name);
- // build a TEXT instruction with a unique pc
- // just to make the rest of the linker happy.
- p = prg();
- p->as = ATEXT;
- p->from.type = D_EXTERN;
- p->from.sym = s;
- p->textflag = 7;
- p->to.type = D_CONST;
- p->link = nil;
- p->pc = pc++;
- s->text = p;
+ s->external = 1;
}
}
@@ -391,16 +379,22 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
if(s == S)
continue;
if(s->sub)
- s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub));
+ s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
if(s->type == STEXT) {
- if(etextp)
- etextp->next = s;
+ if(s->onlist)
+ sysfatal("symbol %s listed multiple times", s->name);
+ s->onlist = 1;
+ if(ctxt->etextp)
+ ctxt->etextp->next = s;
else
- textp = s;
- etextp = s;
+ ctxt->textp = s;
+ ctxt->etextp = s;
for(s = s->sub; s != S; s = s->sub) {
- etextp->next = s;
- etextp = s;
+ if(s->onlist)
+ sysfatal("symbol %s listed multiple times", s->name);
+ s->onlist = 1;
+ ctxt->etextp->next = s;
+ ctxt->etextp = s;
}
}
}
@@ -430,7 +424,7 @@ map(PeObj *obj, PeSect *sect)
static int
readsym(PeObj *obj, int i, PeSym **y)
{
- Sym *s;
+ LSym *s;
PeSym *sym;
char *name, *p;
@@ -464,12 +458,12 @@ readsym(PeObj *obj, int i, PeSym **y)
case IMAGE_SYM_DTYPE_NULL:
switch(sym->sclass) {
case IMAGE_SYM_CLASS_EXTERNAL: //global
- s = lookup(name, 0);
+ s = linklookup(ctxt, name, 0);
break;
case IMAGE_SYM_CLASS_NULL:
case IMAGE_SYM_CLASS_STATIC:
case IMAGE_SYM_CLASS_LABEL:
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
s->dupok = 1;
break;
default:
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index da522dc0c..da6194e4f 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -32,10 +32,14 @@
#include "l.h"
#include "lib.h"
#include "../ld/elf.h"
+#include "../ld/dwarf.h"
#include "../../pkg/runtime/stack.h"
#include "../../pkg/runtime/funcdata.h"
#include <ar.h>
+#if !(defined(_WIN32) || defined(PLAN9))
+#include <sys/stat.h>
+#endif
enum
{
@@ -48,18 +52,9 @@ int iconv(Fmt*);
char symname[] = SYMDEF;
char pkgname[] = "__.PKGDEF";
-char** libdir;
-int nlibdir = 0;
-static int maxlibdir = 0;
static int cout = -1;
-// symbol version, incremented each time a file is loaded.
-// version==1 is reserved for savehist.
-enum
-{
- HistVersion = 1,
-};
-int version = HistVersion;
+extern int version;
// Set if we see an object compiled by the host compiler that is not
// from a package that is known to support internal linking mode.
@@ -77,15 +72,32 @@ Lflag(char *arg)
{
char **p;
- if(nlibdir >= maxlibdir) {
- if (maxlibdir == 0)
- maxlibdir = 8;
+ if(ctxt->nlibdir >= ctxt->maxlibdir) {
+ if (ctxt->maxlibdir == 0)
+ ctxt->maxlibdir = 8;
else
- maxlibdir *= 2;
- p = erealloc(libdir, maxlibdir * sizeof(*p));
- libdir = p;
+ ctxt->maxlibdir *= 2;
+ p = erealloc(ctxt->libdir, ctxt->maxlibdir * sizeof(*p));
+ ctxt->libdir = p;
}
- libdir[nlibdir++] = arg;
+ ctxt->libdir[ctxt->nlibdir++] = arg;
+}
+
+/*
+ * Unix doesn't like it when we write to a running (or, sometimes,
+ * recently run) binary, so remove the output file before writing it.
+ * On Windows 7, remove() can force a subsequent create() to fail.
+ * S_ISREG() does not exist on Plan 9.
+ */
+static void
+mayberemoveoutfile(void)
+{
+#if !(defined(_WIN32) || defined(PLAN9))
+ struct stat st;
+ if(lstat(outfile, &st) == 0 && !S_ISREG(st.st_mode))
+ return;
+#endif
+ remove(outfile);
}
void
@@ -93,12 +105,11 @@ libinit(void)
{
char *suffix, *suffixsep;
+ funcalign = FuncAlign;
fmtinstall('i', iconv);
fmtinstall('Y', Yconv);
fmtinstall('Z', Zconv);
mywhatsys(); // get goroot, goarch, goos
- if(strcmp(goarch, thestring) != 0)
- print("goarch is not known: %s\n", goarch);
// add goroot to the end of the libdir list.
suffix = "";
@@ -112,12 +123,7 @@ libinit(void)
}
Lflag(smprint("%s/pkg/%s_%s%s%s", goroot, goos, goarch, suffixsep, suffix));
- // Unix doesn't like it when we write to a running (or, sometimes,
- // recently run) binary, so remove the output file before writing it.
- // On Windows 7, remove() can force the following create() to fail.
-#ifndef _WIN32
- remove(outfile);
-#endif
+ mayberemoveoutfile();
cout = create(outfile, 1, 0775);
if(cout < 0) {
diag("cannot create %s: %r", outfile);
@@ -132,7 +138,7 @@ libinit(void)
sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos);
}
}
- lookup(INITENTRY, 0)->type = SXREF;
+ linklookup(ctxt, INITENTRY, 0)->type = SXREF;
}
void
@@ -140,165 +146,25 @@ errorexit(void)
{
if(nerrors) {
if(cout >= 0)
- remove(outfile);
+ mayberemoveoutfile();
exits("error");
}
exits(0);
}
void
-addlib(char *src, char *obj)
-{
- char name[1024], pname[1024], comp[256], *p;
- int i, search;
-
- if(histfrogp <= 0)
- return;
-
- search = 0;
- if(histfrog[0]->name[1] == '/') {
- sprint(name, "");
- i = 1;
- } else
- if(isalpha((uchar)histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') {
- strcpy(name, histfrog[0]->name+1);
- i = 1;
- } else
- if(histfrog[0]->name[1] == '.') {
- sprint(name, ".");
- i = 0;
- } else {
- sprint(name, "");
- i = 0;
- search = 1;
- }
-
- for(; i<histfrogp; i++) {
- snprint(comp, sizeof comp, "%s", histfrog[i]->name+1);
- for(;;) {
- p = strstr(comp, "$O");
- if(p == 0)
- break;
- memmove(p+1, p+2, strlen(p+2)+1);
- p[0] = thechar;
- }
- for(;;) {
- p = strstr(comp, "$M");
- if(p == 0)
- break;
- if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
- diag("library component too long");
- return;
- }
- memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
- memmove(p, thestring, strlen(thestring));
- }
- if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
- diag("library component too long");
- return;
- }
- if(i > 0 || !search)
- strcat(name, "/");
- strcat(name, comp);
- }
- cleanname(name);
-
- // runtime.a -> runtime
- p = nil;
- if(strlen(name) > 2 && name[strlen(name)-2] == '.') {
- p = name+strlen(name)-2;
- *p = '\0';
- }
-
- // already loaded?
- for(i=0; i<libraryp; i++)
- if(strcmp(library[i].pkg, name) == 0)
- return;
-
- // runtime -> runtime.a for search
- if(p != nil)
- *p = '.';
-
- if(search) {
- // try dot, -L "libdir", and then goroot.
- for(i=0; i<nlibdir; i++) {
- snprint(pname, sizeof pname, "%s/%s", libdir[i], name);
- if(access(pname, AEXIST) >= 0)
- break;
- }
- }else
- strcpy(pname, name);
- cleanname(pname);
-
- /* runtime.a -> runtime */
- if(p != nil)
- *p = '\0';
-
- if(debug['v'] > 1)
- Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
-
- addlibpath(src, obj, pname, name);
-}
-
-/*
- * add library to library list.
- * srcref: src file referring to package
- * objref: object file referring to package
- * file: object file, e.g., /home/rsc/go/pkg/container/vector.a
- * pkg: package import path, e.g. container/vector
- */
-void
-addlibpath(char *srcref, char *objref, char *file, char *pkg)
-{
- int i;
- Library *l;
- char *p;
-
- for(i=0; i<libraryp; i++)
- if(strcmp(file, library[i].file) == 0)
- return;
-
- if(debug['v'] > 1)
- Bprint(&bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n",
- cputime(), srcref, objref, file, pkg);
-
- if(libraryp == nlibrary){
- nlibrary = 50 + 2*libraryp;
- library = erealloc(library, sizeof library[0] * nlibrary);
- }
-
- l = &library[libraryp++];
-
- p = mal(strlen(objref) + 1);
- strcpy(p, objref);
- l->objref = p;
-
- p = mal(strlen(srcref) + 1);
- strcpy(p, srcref);
- l->srcref = p;
-
- p = mal(strlen(file) + 1);
- strcpy(p, file);
- l->file = p;
-
- p = mal(strlen(pkg) + 1);
- strcpy(p, pkg);
- l->pkg = p;
-}
-
-void
loadinternal(char *name)
{
char pname[1024];
int i, found;
found = 0;
- for(i=0; i<nlibdir; i++) {
- snprint(pname, sizeof pname, "%s/%s.a", libdir[i], name);
+ for(i=0; i<ctxt->nlibdir; i++) {
+ snprint(pname, sizeof pname, "%s/%s.a", ctxt->libdir[i], name);
if(debug['v'])
Bprint(&bso, "searching for %s.a in %s\n", name, pname);
if(access(pname, AEXIST) >= 0) {
- addlibpath("internal", "internal", pname, name);
+ addlibpath(ctxt, "internal", "internal", pname, name);
found = 1;
break;
}
@@ -311,12 +177,13 @@ void
loadlib(void)
{
int i, w, x;
- Sym *s, *gmsym;
+ LSym *s, *gmsym;
+ char* cgostrsym;
if(flag_shared) {
- s = lookup("runtime.islibrary", 0);
+ s = linklookup(ctxt, "runtime.islibrary", 0);
s->dupok = 1;
- adduint8(s, 1);
+ adduint8(ctxt, s, 1);
}
loadinternal("runtime");
@@ -324,27 +191,36 @@ loadlib(void)
loadinternal("math");
if(flag_race)
loadinternal("runtime/race");
- if(linkmode == LinkExternal) {
+
+ for(i=0; i<ctxt->libraryp; i++) {
+ if(debug['v'] > 1)
+ Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), ctxt->library[i].file, ctxt->library[i].objref);
+ iscgo |= strcmp(ctxt->library[i].pkg, "runtime/cgo") == 0;
+ objfile(ctxt->library[i].file, ctxt->library[i].pkg);
+ }
+
+ if(linkmode == LinkExternal && !iscgo) {
// This indicates a user requested -linkmode=external.
// The startup code uses an import of runtime/cgo to decide
// whether to initialize the TLS. So give it one. This could
// be handled differently but it's an unusual case.
loadinternal("runtime/cgo");
+ if(i < ctxt->libraryp)
+ objfile(ctxt->library[i].file, ctxt->library[i].pkg);
+
// Pretend that we really imported the package.
- // This will do no harm if we did in fact import it.
- s = lookup("go.importpath.runtime/cgo.", 0);
+ s = linklookup(ctxt, "go.importpath.runtime/cgo.", 0);
s->type = SDATA;
s->dupok = 1;
s->reachable = 1;
- }
- for(i=0; i<libraryp; i++) {
- if(debug['v'] > 1)
- Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
- iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0;
- objfile(library[i].file, library[i].pkg);
+ // Provided by the code that imports the package.
+ // Since we are simulating the import, we have to provide this string.
+ cgostrsym = "go.string.\"runtime/cgo\"";
+ if(linkrlookup(ctxt, cgostrsym, 0) == nil)
+ addstrdata(cgostrsym, "runtime/cgo");
}
-
+
if(linkmode == LinkAuto) {
if(iscgo && externalobj)
linkmode = LinkExternal;
@@ -355,7 +231,7 @@ loadlib(void)
if(linkmode == LinkInternal) {
// Drop all the cgo_import_static declarations.
// Turns out we won't be needing them.
- for(s = allsym; s != S; s = s->allsym)
+ for(s = ctxt->allsym; s != S; s = s->allsym)
if(s->type == SHOSTOBJ) {
// If a symbol was marked both
// cgo_import_static and cgo_import_dynamic,
@@ -368,14 +244,12 @@ loadlib(void)
}
}
- gmsym = lookup("runtime.tlsgm", 0);
+ gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
gmsym->type = STLSBSS;
gmsym->size = 2*PtrSize;
gmsym->hide = 1;
- if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd)
- gmsym->reachable = 1;
- else
- gmsym->reachable = 0;
+ gmsym->reachable = 1;
+ ctxt->gmsym = gmsym;
// Now that we know the link mode, trim the dynexp list.
x = CgoExportDynamic;
@@ -402,7 +276,9 @@ loadlib(void)
//
// Exception: on OS X, programs such as Shark only work with dynamic
// binaries, so leave it enabled on OS X (Mach-O) binaries.
- if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin)
+ // Also leave it enabled on Solaris which doesn't support
+ // statically linked binaries.
+ if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris)
debug['d'] = 1;
importcycles();
@@ -412,8 +288,8 @@ loadlib(void)
* look for the next file in an archive.
* adapted from libmach.
*/
-int
-nextar(Biobuf *bp, int off, struct ar_hdr *a)
+static vlong
+nextar(Biobuf *bp, vlong off, struct ar_hdr *a)
{
int r;
int32 arsize;
@@ -443,7 +319,7 @@ nextar(Biobuf *bp, int off, struct ar_hdr *a)
void
objfile(char *file, char *pkg)
{
- int32 off, l;
+ vlong off, l;
Biobuf *f;
char magbuf[SARMAG];
char pname[150];
@@ -470,25 +346,24 @@ objfile(char *file, char *pkg)
return;
}
- /* skip over __.GOSYMDEF */
+ /* skip over optional __.GOSYMDEF and process __.PKGDEF */
off = Boffset(f);
- if((l = nextar(f, off, &arhdr)) <= 0) {
+ l = nextar(f, off, &arhdr);
+ if(l <= 0) {
diag("%s: short read on archive file symbol header", file);
goto out;
}
- if(strncmp(arhdr.name, symname, strlen(symname))) {
- diag("%s: first entry not symbol header", file);
- goto out;
- }
- off += l;
-
- /* skip over (or process) __.PKGDEF */
- if((l = nextar(f, off, &arhdr)) <= 0) {
- diag("%s: short read on archive file symbol header", file);
- goto out;
+ if(strncmp(arhdr.name, symname, strlen(symname)) == 0) {
+ off += l;
+ l = nextar(f, off, &arhdr);
+ if(l <= 0) {
+ diag("%s: short read on archive file symbol header", file);
+ goto out;
+ }
}
+
if(strncmp(arhdr.name, pkgname, strlen(pkgname))) {
- diag("%s: second entry not package header", file);
+ diag("%s: cannot find package header", file);
goto out;
}
off += l;
@@ -539,7 +414,7 @@ dowrite(int fd, char *p, int n)
while(n > 0) {
m = write(fd, p, n);
if(m <= 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("write error: %r");
errorexit();
}
@@ -628,7 +503,7 @@ hostobjs(void)
h = &hostobj[i];
f = Bopen(h->file, OREAD);
if(f == nil) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot reopen %s: %r", h->pn);
errorexit();
}
@@ -697,7 +572,7 @@ hostlink(void)
p = strchr(p + 1, ' ');
}
- argv = malloc((13+nhostobj+nldflag+c)*sizeof argv[0]);
+ argv = malloc((14+nhostobj+nldflag+c)*sizeof argv[0]);
argc = 0;
if(extld == nil)
extld = "gcc";
@@ -720,6 +595,8 @@ hostlink(void)
}
if(HEADTYPE == Hdarwin)
argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000";
+ if(HEADTYPE == Hopenbsd)
+ argv[argc++] = "-Wl,-nopie";
if(iself && AssumeGoldLinker)
argv[argc++] = "-Wl,--rosegment";
@@ -738,13 +615,16 @@ hostlink(void)
if(iself)
argv[argc++] = "-rdynamic";
+ if(strstr(argv[0], "clang") != nil)
+ argv[argc++] = "-Qunused-arguments";
+
// already wrote main object file
// copy host objects to temporary directory
for(i=0; i<nhostobj; i++) {
h = &hostobj[i];
f = Bopen(h->file, OREAD);
if(f == nil) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot reopen %s: %r", h->pn);
errorexit();
}
@@ -753,7 +633,7 @@ hostlink(void)
argv[argc++] = p;
w = create(p, 1, 0775);
if(w < 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot create %s: %r", p);
errorexit();
}
@@ -765,7 +645,7 @@ hostlink(void)
len -= n;
}
if(close(w) < 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot write %s: %r", p);
errorexit();
}
@@ -783,6 +663,20 @@ hostlink(void)
if(*p == '\0')
break;
argv[argc++] = p;
+
+ // clang, unlike GCC, passes -rdynamic to the linker
+ // even when linking with -static, causing a linker
+ // error when using GNU ld. So take out -rdynamic if
+ // we added it. We do it in this order, rather than
+ // only adding -rdynamic later, so that -extldflags
+ // can override -rdynamic without using -static.
+ if(iself && strncmp(p, "-static", 7) == 0 && (p[7]==' ' || p[7]=='\0')) {
+ for(i=0; i<argc; i++) {
+ if(strcmp(argv[i], "-rdynamic") == 0)
+ argv[i] = "-static";
+ }
+ }
+
p = strchr(p + 1, ' ');
}
@@ -798,7 +692,7 @@ hostlink(void)
}
if(runcmd(argv) < 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("%s: running %s failed: %r", argv0, argv[0]);
errorexit();
}
@@ -866,8 +760,8 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence)
return;
}
- // First, check that the basic goos, string, and version match.
- t = smprint("%s %s %s ", goos, thestring, getgoversion());
+ // First, check that the basic goos, goarch, and version match.
+ t = smprint("%s %s %s ", goos, getgoarch(), getgoversion());
line[n] = ' ';
if(strncmp(line+10, t, strlen(t)) != 0 && !debug['f']) {
line[n] = '\0';
@@ -913,7 +807,7 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence)
ldpkg(f, pkg, import1 - import0 - 2, pn, whence); // -2 for !\n
Bseek(f, import1, 0);
- ldobj1(f, pkg, eof - Boffset(f), pn);
+ ldobjfile(ctxt, f, pkg, eof - Boffset(f), pn);
free(pn);
return;
@@ -922,318 +816,12 @@ eof:
free(pn);
}
-Sym*
-newsym(char *symb, int v)
-{
- Sym *s;
- int l;
-
- l = strlen(symb) + 1;
- s = mal(sizeof(*s));
- if(debug['v'] > 1)
- Bprint(&bso, "newsym %s\n", symb);
-
- s->dynid = -1;
- s->plt = -1;
- s->got = -1;
- s->name = mal(l + 1);
- memmove(s->name, symb, l);
-
- s->type = 0;
- s->version = v;
- s->value = 0;
- s->sig = 0;
- s->size = 0;
- nsymbol++;
-
- s->allsym = allsym;
- allsym = s;
-
- return s;
-}
-
-static Sym*
-_lookup(char *symb, int v, int creat)
-{
- Sym *s;
- char *p;
- uint32 h;
- int c;
-
- h = v;
- for(p=symb; c = *p; p++)
- h = h+h+h + c;
- // not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it.
- h &= 0xffffff;
- h %= NHASH;
- for(s = hash[h]; s != S; s = s->hash)
- if(strcmp(s->name, symb) == 0)
- return s;
- if(!creat)
- return nil;
-
- s = newsym(symb, v);
- s->extname = s->name;
- s->hash = hash[h];
- hash[h] = s;
-
- return s;
-}
-
-Sym*
-lookup(char *name, int v)
-{
- return _lookup(name, v, 1);
-}
-
-// read-only lookup
-Sym*
-rlookup(char *name, int v)
-{
- return _lookup(name, v, 0);
-}
-
-void
-copyhistfrog(char *buf, int nbuf)
-{
- char *p, *ep;
- int i;
-
- p = buf;
- ep = buf + nbuf;
- for(i=0; i<histfrogp; i++) {
- p = seprint(p, ep, "%s", histfrog[i]->name+1);
- if(i+1<histfrogp && (p == buf || p[-1] != '/'))
- p = seprint(p, ep, "/");
- }
-}
-
-void
-addhist(int32 line, int type)
-{
- Auto *u;
- Sym *s;
- int i, j, k;
-
- u = mal(sizeof(Auto));
- s = mal(sizeof(Sym));
- s->name = mal(2*(histfrogp+1) + 1);
-
- u->asym = s;
- u->type = type;
- u->aoffset = line;
- u->link = curhist;
- curhist = u;
-
- s->name[0] = 0;
- j = 1;
- for(i=0; i<histfrogp; i++) {
- k = histfrog[i]->value;
- s->name[j+0] = k>>8;
- s->name[j+1] = k;
- j += 2;
- }
- s->name[j] = 0;
- s->name[j+1] = 0;
-}
-
-void
-histtoauto(void)
-{
- Auto *l;
-
- while(l = curhist) {
- curhist = l->link;
- l->link = curauto;
- curauto = l;
- }
-}
-
-void
-collapsefrog(Sym *s)
-{
- int i;
-
- /*
- * bad encoding of path components only allows
- * MAXHIST components. if there is an overflow,
- * first try to collapse xxx/..
- */
- for(i=1; i<histfrogp; i++)
- if(strcmp(histfrog[i]->name+1, "..") == 0) {
- memmove(histfrog+i-1, histfrog+i+1,
- (histfrogp-i-1)*sizeof(histfrog[0]));
- histfrogp--;
- goto out;
- }
-
- /*
- * next try to collapse .
- */
- for(i=0; i<histfrogp; i++)
- if(strcmp(histfrog[i]->name+1, ".") == 0) {
- memmove(histfrog+i, histfrog+i+1,
- (histfrogp-i-1)*sizeof(histfrog[0]));
- goto out;
- }
-
- /*
- * last chance, just truncate from front
- */
- memmove(histfrog+0, histfrog+1,
- (histfrogp-1)*sizeof(histfrog[0]));
-
-out:
- histfrog[histfrogp-1] = s;
-}
-
-void
-nuxiinit(void)
-{
- int i, c;
-
- for(i=0; i<4; i++) {
- c = find1(0x04030201L, i+1);
- if(i < 2)
- inuxi2[i] = c;
- if(i < 1)
- inuxi1[i] = c;
- inuxi4[i] = c;
- if(c == i) {
- inuxi8[i] = c;
- inuxi8[i+4] = c+4;
- } else {
- inuxi8[i] = c+4;
- inuxi8[i+4] = c;
- }
- fnuxi4[i] = c;
- fnuxi8[i] = c;
- fnuxi8[i+4] = c+4;
- }
- if(debug['v']) {
- Bprint(&bso, "inuxi = ");
- for(i=0; i<1; i++)
- Bprint(&bso, "%d", inuxi1[i]);
- Bprint(&bso, " ");
- for(i=0; i<2; i++)
- Bprint(&bso, "%d", inuxi2[i]);
- Bprint(&bso, " ");
- for(i=0; i<4; i++)
- Bprint(&bso, "%d", inuxi4[i]);
- Bprint(&bso, " ");
- for(i=0; i<8; i++)
- Bprint(&bso, "%d", inuxi8[i]);
- Bprint(&bso, "\nfnuxi = ");
- for(i=0; i<4; i++)
- Bprint(&bso, "%d", fnuxi4[i]);
- Bprint(&bso, " ");
- for(i=0; i<8; i++)
- Bprint(&bso, "%d", fnuxi8[i]);
- Bprint(&bso, "\n");
- }
- Bflush(&bso);
-}
-
-int
-find1(int32 l, int c)
-{
- char *p;
- int i;
-
- p = (char*)&l;
- for(i=0; i<4; i++)
- if(*p++ == c)
- return i;
- return 0;
-}
-
-int
-find2(int32 l, int c)
-{
- union {
- int32 l;
- short p[2];
- } u;
- short *p;
- int i;
-
- u.l = l;
- p = u.p;
- for(i=0; i<4; i+=2) {
- if(((*p >> 8) & 0xff) == c)
- return i;
- if((*p++ & 0xff) == c)
- return i+1;
- }
- return 0;
-}
-
-int32
-ieeedtof(Ieee *e)
-{
- int exp;
- int32 v;
-
- if(e->h == 0)
- return 0;
- exp = (e->h>>20) & ((1L<<11)-1L);
- exp -= (1L<<10) - 2L;
- v = (e->h & 0xfffffL) << 3;
- v |= (e->l >> 29) & 0x7L;
- if((e->l >> 28) & 1) {
- v++;
- if(v & 0x800000L) {
- v = (v & 0x7fffffL) >> 1;
- exp++;
- }
- }
- if(-148 <= exp && exp <= -126) {
- v |= 1<<23;
- v >>= -125 - exp;
- exp = -126;
- }
- else if(exp < -148 || exp >= 130)
- diag("double fp to single fp overflow: %.17g", ieeedtod(e));
- v |= ((exp + 126) & 0xffL) << 23;
- v |= e->h & 0x80000000L;
- return v;
-}
-
-double
-ieeedtod(Ieee *ieeep)
-{
- Ieee e;
- double fr;
- int exp;
-
- if(ieeep->h & (1L<<31)) {
- e.h = ieeep->h & ~(1L<<31);
- e.l = ieeep->l;
- return -ieeedtod(&e);
- }
- if(ieeep->l == 0 && ieeep->h == 0)
- return 0;
- exp = (ieeep->h>>20) & ((1L<<11)-1L);
- exp -= (1L<<10) - 2L;
- fr = ieeep->l & ((1L<<16)-1L);
- fr /= 1L<<16;
- fr += (ieeep->l>>16) & ((1L<<16)-1L);
- fr /= 1L<<16;
- if(exp == -(1L<<10) - 2L) {
- fr += (ieeep->h & (1L<<20)-1L);
- exp++;
- } else
- fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
- fr /= 1L<<21;
- return ldexp(fr, exp);
-}
-
void
zerosig(char *sp)
{
- Sym *s;
+ LSym *s;
- s = lookup(sp, 0);
+ s = linklookup(ctxt, sp, 0);
s->sig = 0;
}
@@ -1242,7 +830,10 @@ mywhatsys(void)
{
goroot = getgoroot();
goos = getgoos();
- goarch = thestring; // ignore $GOARCH - we know who we are
+ goarch = getgoarch();
+
+ if(strncmp(goarch, thestring, strlen(thestring)) != 0)
+ sysfatal("cannot use %cc with GOARCH=%s", thechar, goarch);
}
int
@@ -1303,7 +894,8 @@ unmal(void *v, uint32 n)
* Invalid bytes turn into %xx. Right now the only bytes that need
* escaping are %, ., and ", but we escape all control characters too.
*
- * Must be same as ../gc/subr.c:/^pathtoprefix.
+ * If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
+ * If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too.
*/
static char*
pathtoprefix(char *s)
@@ -1357,13 +949,6 @@ iconv(Fmt *fp)
return 0;
}
-void
-mangle(char *file)
-{
- fprint(2, "%s: mangled input file\n", file);
- errorexit();
-}
-
Section*
addsection(Segment *seg, char *name, int rwx)
{
@@ -1381,235 +966,6 @@ addsection(Segment *seg, char *name, int rwx)
return sect;
}
-void
-addvarint(Sym *s, uint32 val)
-{
- int32 n;
- uint32 v;
- uchar *p;
-
- n = 0;
- for(v = val; v >= 0x80; v >>= 7)
- n++;
- n++;
-
- symgrow(s, s->np+n);
-
- p = s->p + s->np - n;
- for(v = val; v >= 0x80; v >>= 7)
- *p++ = v | 0x80;
- *p = v;
-}
-
-// funcpctab appends 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
-// current value is, for each p,
-//
-// val = valfunc(func, val, p, 0, arg);
-// record val as value at p->pc;
-// val = valfunc(func, val, p, 1, arg);
-//
-// 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.
-void
-funcpctab(Sym *dst, Sym *func, char *desc, int32 (*valfunc)(Sym*, int32, Prog*, int32, int32), int32 arg)
-{
- int dbg, i, start;
- 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;
-
- debug['O'] += dbg;
-
- start = dst->np;
-
- if(debug['O'])
- Bprint(&bso, "funcpctab %s -> %s [valfunc=%s]\n", func->name, dst->name, desc);
-
- val = -1;
- oldval = val;
- pc = func->value;
-
- if(debug['O'])
- Bprint(&bso, "%6llux %6d %P\n", pc, val, func->text);
-
- started = 0;
- for(p=func->text; p != P; p = p->link) {
- // Update val. If it's not changing, keep going.
- val = valfunc(func, val, p, 0, arg);
- if(val == oldval && started) {
- val = valfunc(func, val, p, 1, arg);
- if(debug['O'])
- Bprint(&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(func, val, p, 1, arg);
- if(debug['O'])
- Bprint(&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(debug['O'])
- Bprint(&bso, "%6llux %6d %P\n", (vlong)p->pc, val, p);
-
- if(started) {
- addvarint(dst, (p->pc - pc) / MINLC);
- pc = p->pc;
- }
- delta = val - oldval;
- if(delta>>31)
- delta = 1 | ~(delta<<1);
- else
- delta <<= 1;
- addvarint(dst, delta);
- oldval = val;
- started = 1;
- val = valfunc(func, val, p, 1, arg);
- }
-
- if(started) {
- if(debug['O'])
- Bprint(&bso, "%6llux done\n", (vlong)func->value+func->size);
- addvarint(dst, (func->value+func->size - pc) / MINLC);
- addvarint(dst, 0); // terminator
- }
-
- if(debug['O']) {
- Bprint(&bso, "wrote %d bytes\n", dst->np - start);
- for(i=start; i<dst->np; i++)
- Bprint(&bso, " %02ux", dst->p[i]);
- Bprint(&bso, "\n");
- }
-
- debug['O'] -= 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(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg)
-{
- int32 f, l;
-
- if(p->as == ATEXT || p->as == ANOP || p->as == AUSEFIELD || p->line == 0 || phase == 1)
- return oldval;
- getline(sym->hist, p->line, &f, &l);
- if(f == 0) {
- // print("getline failed for %s %P\n", cursym->name, p);
- return oldval;
- }
- if(arg == 0)
- return f;
- return l;
-}
-
-// 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(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 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) {
- diag("overflow in spadj: %d + %d = %d", oldval, p->spadj, oldval + p->spadj);
- errorexit();
- }
- 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(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg)
-{
- USED(sym);
-
- if(phase == 0 || p->as != APCDATA || p->from.offset != arg)
- return oldval;
- if((int32)p->to.offset != p->to.offset) {
- diag("overflow in PCDATA instruction: %P", p);
- errorexit();
- }
- return p->to.offset;
-}
-
-#define LOG 5
-void
-mkfwd(void)
-{
- 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] = P;
- }
- i = 0;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- if(p->link == P) {
- if(cursym->next)
- p->forwd = cursym->next->text;
- break;
- }
- i--;
- if(i < 0)
- i = LOG-1;
- p->forwd = P;
- dwn[i]--;
- if(dwn[i] <= 0) {
- dwn[i] = cnt[i];
- if(lst[i] != P)
- lst[i]->forwd = p;
- lst[i] = p;
- }
- }
- }
-}
-
uint16
le16(uchar *b)
{
@@ -1652,7 +1008,7 @@ Endian le = { le16, le32, le64 };
typedef struct Chain Chain;
struct Chain
{
- Sym *sym;
+ LSym *sym;
Chain *up;
int limit; // limit on entry to sym
};
@@ -1660,67 +1016,87 @@ struct Chain
static int stkcheck(Chain*, int);
static void stkprint(Chain*, int);
static void stkbroke(Chain*, int);
-static Sym *morestack;
-static Sym *newstack;
+static LSym *morestack;
+static LSym *newstack;
enum
{
HasLinkRegister = (thechar == '5'),
- CallSize = (!HasLinkRegister)*PtrSize, // bytes of stack required for a call
};
+// TODO: Record enough information in new object files to
+// allow stack checks here.
+
+static int
+callsize(void)
+{
+ if(thechar == '5')
+ return 0;
+ return RegSize;
+}
+
void
dostkcheck(void)
{
Chain ch;
- Sym *s;
+ LSym *s;
- morestack = lookup("runtime.morestack", 0);
- newstack = lookup("runtime.newstack", 0);
-
- // First the nosplits on their own.
- for(s = textp; s != nil; s = s->next) {
- if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) == 0)
+ morestack = linklookup(ctxt, "runtime.morestack", 0);
+ newstack = linklookup(ctxt, "runtime.newstack", 0);
+
+ // Every splitting function ensures that there are at least StackLimit
+ // bytes available below SP when the splitting prologue finishes.
+ // If the splitting function calls F, then F begins execution with
+ // at least StackLimit - callsize() bytes available.
+ // Check that every function behaves correctly with this amount
+ // of stack, following direct calls in order to piece together chains
+ // of non-splitting functions.
+ ch.up = nil;
+ ch.limit = StackLimit - callsize();
+
+ // Check every function, but do the nosplit functions in a first pass,
+ // to make the printed failure chains as short as possible.
+ for(s = ctxt->textp; s != nil; s = s->next) {
+ // runtime.racesymbolizethunk is called from gcc-compiled C
+ // code running on the operating system thread stack.
+ // It uses more than the usual amount of stack but that's okay.
+ if(strcmp(s->name, "runtime.racesymbolizethunk") == 0)
continue;
- cursym = s;
- ch.up = nil;
+
+ if(s->nosplit) {
+ ctxt->cursym = s;
ch.sym = s;
- ch.limit = StackLimit - CallSize;
stkcheck(&ch, 0);
- s->stkcheck = 1;
}
-
- // Check calling contexts.
- // Some nosplits get called a little further down,
- // like newproc and deferproc. We could hard-code
- // that knowledge but it's more robust to look at
- // the actual call sites.
- for(s = textp; s != nil; s = s->next) {
- if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) != 0)
- continue;
- cursym = s;
- ch.up = nil;
+ }
+ for(s = ctxt->textp; s != nil; s = s->next) {
+ if(!s->nosplit) {
+ ctxt->cursym = s;
ch.sym = s;
- ch.limit = StackLimit - CallSize;
stkcheck(&ch, 0);
}
}
+}
static int
stkcheck(Chain *up, int depth)
{
Chain ch, ch1;
- Prog *p;
- Sym *s;
- int limit, prolog;
+ LSym *s;
+ int limit;
+ Reloc *r, *endr;
+ Pciter pcsp;
limit = up->limit;
s = up->sym;
- p = s->text;
- // Small optimization: don't repeat work at top.
- if(s->stkcheck && limit == StackLimit-CallSize)
+ // Don't duplicate work: only need to consider each
+ // function at top of safe zone once.
+ if(limit == StackLimit-callsize()) {
+ if(s->stkcheck)
return 0;
+ s->stkcheck = 1;
+ }
if(depth > 100) {
diag("nosplit stack check too deep");
@@ -1728,11 +1104,11 @@ stkcheck(Chain *up, int depth)
return -1;
}
- if(p == nil || p->link == nil) {
+ if(s->external || s->pcln == nil) {
// external function.
// should never be called directly.
// only diagnose the direct caller.
- if(depth == 1)
+ if(depth == 1 && s->type != SXREF)
diag("call to external function %s", s->name);
return -1;
}
@@ -1748,50 +1124,56 @@ stkcheck(Chain *up, int depth)
return 0;
ch.up = up;
- prolog = (s->text->textflag & NOSPLIT) == 0;
- for(p = s->text; p != P; p = p->link) {
- limit -= p->spadj;
- if(prolog && p->spadj != 0) {
- // The first stack adjustment in a function with a
- // split-checking prologue marks the end of the
- // prologue. Assuming the split check is correct,
- // after the adjustment there should still be at least
- // StackLimit bytes available below the stack pointer.
- // If this is not the top call in the chain, no need
- // to duplicate effort, so just stop.
- if(depth > 0)
- return 0;
- prolog = 0;
- limit = StackLimit;
- }
- if(limit < 0) {
- stkbroke(up, limit);
+
+ // Walk through sp adjustments in function, consuming relocs.
+ r = s->r;
+ endr = r + s->nr;
+ for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp)) {
+ // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
+
+ // Check stack size in effect for this span.
+ if(limit - pcsp.value < 0) {
+ stkbroke(up, limit - pcsp.value);
return -1;
}
- if(iscall(p)) {
- limit -= CallSize;
- ch.limit = limit;
- if(p->to.type == D_BRANCH) {
+
+ // Process calls in this span.
+ for(; r < endr && r->off < pcsp.nextpc; r++) {
+ switch(r->type) {
+ case R_CALL:
+ case R_CALLARM:
// Direct call.
- ch.sym = p->to.sym;
+ ch.limit = limit - pcsp.value - callsize();
+ ch.sym = r->sym;
if(stkcheck(&ch, depth+1) < 0)
return -1;
- } else {
- // Indirect call. Assume it is a splitting function,
+
+ // If this is a call to morestack, we've just raised our limit back
+ // to StackLimit beyond the frame size.
+ if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
+ limit = StackLimit + s->locals;
+ if(thechar == '5')
+ limit += 4; // saved LR
+ }
+ break;
+
+ case R_CALLIND:
+ // Indirect call. Assume it is a call to a splitting function,
// so we have to make sure it can call morestack.
- limit -= CallSize;
+ // Arrange the data structures to report both calls, so that
+ // if there is an error, stkprint shows all the steps involved.
+ ch.limit = limit - pcsp.value - callsize();
ch.sym = nil;
- ch1.limit = limit;
+ ch1.limit = ch.limit - callsize(); // for morestack in called prologue
ch1.up = &ch;
ch1.sym = morestack;
if(stkcheck(&ch1, depth+2) < 0)
return -1;
- limit += CallSize;
+ break;
}
- limit += CallSize;
+ }
}
- }
return 0;
}
@@ -1814,7 +1196,7 @@ stkprint(Chain *ch, int limit)
if(ch->up == nil) {
// top of chain. ch->sym != nil.
- if(ch->sym->text->textflag & NOSPLIT)
+ if(ch->sym->nosplit)
print("\t%d\tassumed on entry to %s\n", ch->limit, name);
else
print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
@@ -1828,52 +1210,14 @@ stkprint(Chain *ch, int limit)
}
int
-headtype(char *name)
-{
- int i;
-
- for(i=0; headers[i].name; i++)
- if(strcmp(name, headers[i].name) == 0) {
- headstring = headers[i].name;
- return headers[i].val;
- }
- fprint(2, "unknown header type -H %s\n", name);
- errorexit();
- return -1; // not reached
-}
-
-char*
-headstr(int v)
-{
- static char buf[20];
- int i;
-
- for(i=0; headers[i].name; i++)
- if(v == headers[i].val)
- return headers[i].name;
- snprint(buf, sizeof buf, "%d", v);
- return buf;
-}
-
-void
-undef(void)
-{
- Sym *s;
-
- for(s = allsym; s != S; s = s->allsym)
- if(s->type == SXREF)
- diag("%s(%d): not defined", s->name, s->version);
-}
-
-int
Yconv(Fmt *fp)
{
- Sym *s;
+ LSym *s;
Fmt fmt;
int i;
char *str;
- s = va_arg(fp->args, Sym*);
+ s = va_arg(fp->args, LSym*);
if (s == S) {
fmtprint(fp, "<nil>");
} else {
@@ -1967,6 +1311,14 @@ usage(void)
void
setheadtype(char *s)
{
+ int h;
+
+ h = headtype(s);
+ if(h < 0) {
+ fprint(2, "unknown header type -H %s\n", s);
+ errorexit();
+ }
+ headstring = s;
HEADTYPE = headtype(s);
}
@@ -1985,22 +1337,22 @@ doversion(void)
}
void
-genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
+genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
{
Auto *a;
- Sym *s;
+ LSym *s;
int32 off;
// These symbols won't show up in the first loop below because we
// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
- s = lookup("text", 0);
+ s = linklookup(ctxt, "text", 0);
if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0);
- s = lookup("etext", 0);
+ s = linklookup(ctxt, "etext", 0);
if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0);
- for(s=allsym; s!=S; s=s->allsym) {
+ for(s=ctxt->allsym; s!=S; s=s->allsym) {
if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0))
continue;
switch(s->type&SMASK) {
@@ -2036,20 +1388,20 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
}
}
- for(s = textp; s != nil; s = s->next) {
- if(s->text == nil)
- continue;
-
+ for(s = ctxt->textp; s != nil; s = s->next) {
put(s, s->name, 'T', s->value, s->size, s->version, s->gotype);
+ // NOTE(ality): acid can't produce a stack trace without .frame symbols
+ put(nil, ".frame", 'm', s->locals+PtrSize, 0, 0, 0);
+
for(a=s->autom; a; a=a->link) {
// Emit a or p according to actual offset, even if label is wrong.
// This avoids negative offsets, which cannot be encoded.
- if(a->type != D_AUTO && a->type != D_PARAM)
+ if(a->type != A_AUTO && a->type != A_PARAM)
continue;
// compute offset relative to FP
- if(a->type == D_PARAM)
+ if(a->type == A_PARAM)
off = a->aoffset;
else
off = a->aoffset - PtrSize;
@@ -2075,461 +1427,126 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
Bflush(&bso);
}
-char*
-estrdup(char *p)
-{
- p = strdup(p);
- if(p == nil) {
- cursym = S;
- diag("out of memory");
- errorexit();
- }
- return p;
-}
-
-void*
-erealloc(void *p, long n)
+vlong
+symaddr(LSym *s)
{
- p = realloc(p, n);
- if(p == nil) {
- cursym = S;
- diag("out of memory");
- errorexit();
- }
- return p;
+ if(!s->reachable)
+ diag("unreachable symbol in symaddr - %s", s->name);
+ return s->value;
}
-// Saved history stacks encountered while reading archives.
-// Keeping them allows us to answer virtual lineno -> file:line
-// queries.
-//
-// The history stack is a complex data structure, described best at the
-// bottom of http://plan9.bell-labs.com/magic/man2html/6/a.out.
-// One of the key benefits of interpreting it here is that the runtime
-// does not have to. Perhaps some day the compilers could generate
-// a simpler linker input too.
-
-struct Hist
-{
- int32 line;
- int32 off;
- Sym *file;
-};
-
-static Hist *histcopy;
-static Hist *hist;
-static int32 nhist;
-static int32 maxhist;
-static int32 histdepth;
-static int32 nhistfile;
-static Sym *filesyms;
-
-// savehist processes a single line, off history directive
-// found in the input object file.
void
-savehist(int32 line, int32 off)
+xdefine(char *p, int t, vlong v)
{
- char tmp[1024];
- Sym *file;
- Hist *h;
-
- // NOTE(rsc): We used to do the copyhistfrog first and this
- // condition was if(tmp[0] != '\0') to check for an empty string,
- // implying that histfrogp == 0, implying that this is a history pop.
- // However, on Windows in the misc/cgo test, the linker is
- // presented with an ANAME corresponding to an empty string,
- // that ANAME ends up being the only histfrog, and thus we have
- // a situation where histfrogp > 0 (not a pop) but the path we find
- // is the empty string. Really that shouldn't happen, but it doesn't
- // seem to be bothering anyone yet, and it's easier to fix the condition
- // to test histfrogp than to track down where that empty string is
- // coming from. Probably it is coming from go tool pack's P command.
- if(histfrogp > 0) {
- tmp[0] = '\0';
- copyhistfrog(tmp, sizeof tmp);
- file = lookup(tmp, HistVersion);
- if(file->type != SFILEPATH) {
- file->value = ++nhistfile;
- file->type = SFILEPATH;
- file->next = filesyms;
- filesyms = file;
- }
- } else
- file = nil;
+ LSym *s;
- if(file != nil && line == 1 && off == 0) {
- // start of new stack
- if(histdepth != 0) {
- diag("history stack phase error: unexpected start of new stack depth=%d file=%s", histdepth, tmp);
- errorexit();
- }
- nhist = 0;
- histcopy = nil;
- }
-
- if(nhist >= maxhist) {
- if(maxhist == 0)
- maxhist = 1;
- maxhist *= 2;
- hist = erealloc(hist, maxhist*sizeof hist[0]);
- }
- h = &hist[nhist++];
- h->line = line;
- h->off = off;
- h->file = file;
-
- if(file != nil) {
- if(off == 0)
- histdepth++;
- } else {
- if(off != 0) {
- diag("history stack phase error: bad offset in pop");
- errorexit();
- }
- histdepth--;
- }
+ s = linklookup(ctxt, p, 0);
+ s->type = t;
+ s->value = v;
+ s->reachable = 1;
+ s->special = 1;
}
-// gethist returns the history stack currently in effect.
-// The result is valid indefinitely.
-Hist*
-gethist(void)
+vlong
+datoff(vlong addr)
{
- if(histcopy == nil) {
- if(nhist == 0)
- return nil;
- histcopy = mal((nhist+1)*sizeof hist[0]);
- memmove(histcopy, hist, nhist*sizeof hist[0]);
- histcopy[nhist].line = -1;
- }
- return histcopy;
+ if(addr >= segdata.vaddr)
+ return addr - segdata.vaddr + segdata.fileoff;
+ if(addr >= segtext.vaddr)
+ return addr - segtext.vaddr + segtext.fileoff;
+ diag("datoff %#llx", addr);
+ return 0;
}
-typedef struct Hstack Hstack;
-struct Hstack
-{
- Hist *h;
- int delta;
-};
-
-// getline sets *f to the file number and *l to the line number
-// of the virtual line number line according to the history stack h.
-void
-getline(Hist *h, int32 line, int32 *f, int32 *l)
+vlong
+entryvalue(void)
{
- Hstack stk[100];
- int nstk, start;
- Hist *top, *h0;
- static Hist *lasth;
- static int32 laststart, lastend, lastdelta, lastfile;
-
- h0 = h;
- *f = 0;
- *l = 0;
- start = 0;
- if(h == nil || line == 0) {
- print("%s: getline: h=%p line=%d\n", cursym->name, h, line);
- return;
- }
-
- // Cache span used during last lookup, so that sequential
- // translation of line numbers in compiled code is efficient.
- if(!debug['O'] && lasth == h && laststart <= line && line < lastend) {
- *f = lastfile;
- *l = line - lastdelta;
- return;
- }
-
- if(debug['O'])
- print("getline %d laststart=%d lastend=%d\n", line, laststart, lastend);
-
- nstk = 0;
- for(; h->line != -1; h++) {
- if(debug['O'])
- print("\t%s %d %d\n", h->file ? h->file->name : "?", h->line, h->off);
-
- if(h->line > line) {
- if(nstk == 0) {
- diag("history stack phase error: empty stack at line %d", (int)line);
- errorexit();
- }
- top = stk[nstk-1].h;
- lasth = h;
- lastfile = top->file->value;
- laststart = start;
- lastend = h->line;
- lastdelta = stk[nstk-1].delta;
- *f = lastfile;
- *l = line - lastdelta;
- if(debug['O'])
- print("\tgot %d %d [%d %d %d]\n", *f, *l, laststart, lastend, lastdelta);
- return;
- }
- if(h->file == nil) {
- // pop included file
- if(nstk == 0) {
- diag("history stack phase error: stack underflow");
- errorexit();
- }
- nstk--;
- if(nstk > 0)
- stk[nstk-1].delta += h->line - stk[nstk].h->line;
- start = h->line;
- } else if(h->off == 0) {
- // push included file
- if(nstk >= nelem(stk)) {
- diag("history stack phase error: stack overflow");
- errorexit();
- }
- start = h->line;
- stk[nstk].h = h;
- stk[nstk].delta = h->line - 1;
- nstk++;
- } else {
- // #line directive
- if(nstk == 0) {
- diag("history stack phase error: stack underflow");
- errorexit();
- }
- stk[nstk-1].h = h;
- stk[nstk-1].delta = h->line - h->off;
- start = h->line;
- }
- if(debug['O'])
- print("\t\tnstk=%d delta=%d\n", nstk, stk[nstk].delta);
- }
+ char *a;
+ LSym *s;
- diag("history stack phase error: cannot find line for %d", line);
- nstk = 0;
- for(h = h0; h->line != -1; h++) {
- print("\t%d %d %s\n", h->line, h->off, h->file ? h->file->name : "");
- if(h->file == nil)
- nstk--;
- else if(h->off == 0)
- nstk++;
- }
+ a = INITENTRY;
+ if(*a >= '0' && *a <= '9')
+ return atolwhex(a);
+ s = linklookup(ctxt, a, 0);
+ if(s->type == 0)
+ return INITTEXT;
+ if(s->type != STEXT)
+ diag("entry not text: %s", s->name);
+ return s->value;
}
-// defgostring returns a symbol for the Go string containing text.
-Sym*
-defgostring(char *text)
+static void
+undefsym(LSym *s)
{
- char *p;
- Sym *s;
- int32 n;
-
- n = strlen(text);
- p = smprint("go.string.\"%Z\"", text);
- s = lookup(p, 0);
- if(s->size == 0) {
- s->type = SGOSTRING;
- s->reachable = 1;
- s->size = 2*PtrSize+n;
- symgrow(s, 2*PtrSize+n);
- setaddrplus(s, 0, s, 2*PtrSize);
- setuintxx(s, PtrSize, n, PtrSize);
- memmove(s->p+2*PtrSize, text, n);
- }
- s->reachable = 1;
- return s;
-}
+ int i;
+ Reloc *r;
-// addpctab appends to f a pc-value table, storing its offset at off.
-// The pc-value table is for func and reports the value of valfunc
-// parameterized by arg.
-static int32
-addpctab(Sym *f, int32 off, Sym *func, char *desc, int32 (*valfunc)(Sym*, int32, Prog*, int32, int32), int32 arg)
-{
- int32 start;
-
- start = f->np;
- funcpctab(f, func, desc, valfunc, arg);
- if(start == f->np) {
- // no table
- return setuint32(f, off, 0);
- }
- if((int32)start > (int32)f->np) {
- diag("overflow adding pc-table: symbol too large");
- errorexit();
+ ctxt->cursym = s;
+ for(i=0; i<s->nr; i++) {
+ r = &s->r[i];
+ if(r->sym == nil) // happens for some external ARM relocs
+ continue;
+ if(r->sym->type == Sxxx || r->sym->type == SXREF)
+ diag("undefined: %s", r->sym->name);
+ if(!r->sym->reachable)
+ diag("use of unreachable symbol: %s", r->sym->name);
}
- return setuint32(f, off, start);
}
-static int32
-ftabaddstring(Sym *ftab, char *s)
+void
+undef(void)
{
- int32 n, start;
+ LSym *s;
- n = strlen(s)+1;
- start = ftab->np;
- symgrow(ftab, start+n+1);
- strcpy((char*)ftab->p + start, s);
- return start;
+ for(s = ctxt->textp; s != nil; s = s->next)
+ undefsym(s);
+ for(s = datap; s != nil; s = s->next)
+ undefsym(s);
+ if(nerrors > 0)
+ errorexit();
}
-// pclntab initializes the pclntab symbol with
-// runtime function and file name information.
void
-pclntab(void)
+callgraph(void)
{
- Prog *p;
- int32 i, n, nfunc, start, funcstart;
- uint32 *havepc, *havefunc;
- Sym *ftab, *s;
- int32 npcdata, nfuncdata, off, end;
- int64 funcdata_bytes;
-
- funcdata_bytes = 0;
- ftab = lookup("pclntab", 0);
- ftab->type = SPCLNTAB;
- ftab->reachable = 1;
-
- // See golang.org/s/go12symtab for the format. Briefly:
- // 8-byte header
- // nfunc [PtrSize bytes]
- // function table, alternating PC and offset to func struct [each entry PtrSize bytes]
- // end PC [PtrSize bytes]
- // offset to file table [4 bytes]
- nfunc = 0;
- for(cursym = textp; cursym != nil; cursym = cursym->next)
- nfunc++;
- symgrow(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize+4);
- setuint32(ftab, 0, 0xfffffffb);
- setuint8(ftab, 6, MINLC);
- setuint8(ftab, 7, PtrSize);
- setuintxx(ftab, 8, nfunc, PtrSize);
-
- nfunc = 0;
- for(cursym = textp; cursym != nil; cursym = cursym->next, nfunc++) {
- funcstart = ftab->np;
- funcstart += -ftab->np & (PtrSize-1);
-
- setaddr(ftab, 8+PtrSize+nfunc*2*PtrSize, cursym);
- setuintxx(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, funcstart, PtrSize);
-
- npcdata = 0;
- nfuncdata = 0;
- for(p = cursym->text; p != P; 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;
- }
-
- // fixed size of struct, checked below
- off = funcstart;
- end = funcstart + PtrSize + 3*4 + 5*4 + npcdata*4 + nfuncdata*PtrSize;
- if(nfuncdata > 0 && (end&(PtrSize-1)))
- end += 4;
- symgrow(ftab, end);
-
- // entry uintptr
- off = setaddr(ftab, off, cursym);
-
- // name int32
- off = setuint32(ftab, off, ftabaddstring(ftab, cursym->name));
-
- // args int32
- // TODO: Move into funcinfo.
- if(cursym->text == nil)
- off = setuint32(ftab, off, ArgsSizeUnknown);
- else
- off = setuint32(ftab, off, cursym->args);
-
- // frame int32
- // TODO: Remove entirely. The pcsp table is more precise.
- // This is only used by a fallback case during stack walking
- // when a called function doesn't have argument information.
- // We need to make sure everything has argument information
- // and then remove this.
- if(cursym->text == nil)
- off = setuint32(ftab, off, 0);
- else
- off = setuint32(ftab, off, (uint32)cursym->text->to.offset+PtrSize);
-
- // pcsp table (offset int32)
- off = addpctab(ftab, off, cursym, "pctospadj", pctospadj, 0);
-
- // pcfile table (offset int32)
- off = addpctab(ftab, off, cursym, "pctofileline file", pctofileline, 0);
+ LSym *s;
+ Reloc *r;
+ int i;
- // pcln table (offset int32)
- off = addpctab(ftab, off, cursym, "pctofileline line", pctofileline, 1);
-
- // npcdata int32
- off = setuint32(ftab, off, npcdata);
-
- // nfuncdata int32
- off = setuint32(ftab, off, nfuncdata);
-
- // tabulate which pc and func data we have.
- n = ((npcdata+31)/32 + (nfuncdata+31)/32)*4;
- havepc = mal(n);
- havefunc = havepc + (npcdata+31)/32;
- for(p = cursym->text; p != P; p = p->link) {
- if(p->as == AFUNCDATA) {
- if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1)
- 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);
- }
+ if(!debug['c'])
+ return;
- // pcdata.
- for(i=0; i<npcdata; i++) {
- if(!(havepc[i/32]>>(i%32))&1) {
- off = setuint32(ftab, off, 0);
+ for(s = ctxt->textp; s != nil; s = s->next) {
+ for(i=0; i<s->nr; i++) {
+ r = &s->r[i];
+ if(r->sym == nil)
continue;
- }
- off = addpctab(ftab, off, cursym, "pctopcdata", pctopcdata, i);
- }
-
- unmal(havepc, n);
-
- // funcdata, must be pointer-aligned and we're only int32-aligned.
- // Unlike pcdata, can gather in a single pass.
- // Missing funcdata will be 0 (nil pointer).
- if(nfuncdata > 0) {
- if(off&(PtrSize-1))
- off += 4;
- for(p = cursym->text; p != P; p = p->link) {
- if(p->as == AFUNCDATA) {
- i = p->from.offset;
- if(p->to.type == D_CONST)
- setuintxx(ftab, off+PtrSize*i, p->to.offset, PtrSize);
- else {
- // TODO: Dedup.
- funcdata_bytes += p->to.sym->size;
- setaddrplus(ftab, off+PtrSize*i, p->to.sym, p->to.offset);
- }
- }
- }
- off += nfuncdata*PtrSize;
- }
-
- if(off != end) {
- diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d)", funcstart, off, end, npcdata, nfuncdata);
- errorexit();
+ if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT)
+ Bprint(&bso, "%s calls %s\n", s->name, r->sym->name);
}
-
- // Final entry of table is just end pc.
- if(cursym->next == nil)
- setaddrplus(ftab, 8+PtrSize+(nfunc+1)*2*PtrSize, cursym, cursym->size);
}
-
- // Start file table.
- start = ftab->np;
- start += -ftab->np & (PtrSize-1);
- setuint32(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, start);
+}
- symgrow(ftab, start+(nhistfile+1)*4);
- setuint32(ftab, start, nhistfile);
- for(s = filesyms; s != S; s = s->next)
- setuint32(ftab, start + s->value*4, ftabaddstring(ftab, s->name));
+void
+diag(char *fmt, ...)
+{
+ char buf[1024], *tn, *sep;
+ va_list arg;
- ftab->size = ftab->np;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
-}
+ tn = "";
+ sep = "";
+ if(ctxt->cursym != S) {
+ tn = ctxt->cursym->name;
+ sep = ": ";
+ }
+ va_start(arg, fmt);
+ vseprint(buf, buf+sizeof(buf), fmt, arg);
+ va_end(arg);
+ print("%s%s%s\n", tn, sep, buf);
+
+ nerrors++;
+ if(nerrors > 20) {
+ print("too many errors\n");
+ errorexit();
+ }
+}
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index be95bb46e..7267c6371 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -28,68 +28,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-enum
-{
- Sxxx,
-
- /* order here is order in output file */
- /* readonly, executable */
- STEXT,
- SELFRXSECT,
-
- /* readonly, non-executable */
- STYPE,
- SSTRING,
- SGOSTRING,
- SGOFUNC,
- SRODATA,
- SFUNCTAB,
- STYPELINK,
- SSYMTAB, // TODO: move to unmapped section
- SPCLNTAB,
- SELFROSECT,
-
- /* writable, non-executable */
- SMACHOPLT,
- SELFSECT,
- SMACHO, /* Mach-O __nl_symbol_ptr */
- SMACHOGOT,
- SNOPTRDATA,
- SINITARR,
- SDATA,
- SWINDOWS,
- SBSS,
- SNOPTRBSS,
- STLSBSS,
-
- /* not mapped */
- SXREF,
- SMACHOSYMSTR,
- SMACHOSYMTAB,
- SMACHOINDIRECTPLT,
- SMACHOINDIRECTGOT,
- SFILE,
- SFILEPATH,
- SCONST,
- SDYNIMPORT,
- SHOSTOBJ,
-
- SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
- SMASK = SSUB - 1,
- SHIDDEN = 1<<9, // hidden or local symbol
-
- NHASH = 100003,
-};
-
-typedef struct Library Library;
-struct Library
-{
- char *objref; // object where we found the reference
- char *srcref; // src file where we found the reference
- char *file; // object file
- char *pkg; // import path
-};
-
// Terrible but standard terminology.
// A segment describes a block of file to load into memory.
// A section further describes the pieces of that block for
@@ -125,39 +63,18 @@ struct Section
uvlong rellen;
};
-typedef struct Hist Hist;
-
-#pragma incomplete struct Hist
-
extern char symname[];
-extern char **libdir;
-extern int nlibdir;
-extern int version;
EXTERN char* INITENTRY;
-EXTERN char* thestring;
-EXTERN Library* library;
-EXTERN int libraryp;
-EXTERN int nlibrary;
-EXTERN Sym* hash[NHASH];
-EXTERN Sym* allsym;
-EXTERN Sym* histfrog[MAXHIST];
-EXTERN uchar fnuxi8[8];
-EXTERN uchar fnuxi4[4];
-EXTERN int histfrogp;
-EXTERN int histgen;
-EXTERN uchar inuxi1[1];
-EXTERN uchar inuxi2[2];
-EXTERN uchar inuxi4[4];
-EXTERN uchar inuxi8[8];
+extern char* thestring;
+extern LinkArch* thelinkarch;
EXTERN char* outfile;
-EXTERN int32 nsymbol;
-EXTERN char* thestring;
EXTERN int ndynexp;
-EXTERN Sym** dynexp;
+EXTERN LSym** dynexp;
EXTERN int nldflag;
EXTERN char** ldflag;
EXTERN int havedynamic;
+EXTERN int funcalign;
EXTERN int iscgo;
EXTERN int elfglobalsymndx;
EXTERN char* flag_installsuffix;
@@ -169,16 +86,21 @@ EXTERN char* tmpdir;
EXTERN char* extld;
EXTERN char* extldflags;
EXTERN int debug_s; // backup old value of debug['s']
+EXTERN Link* ctxt;
+EXTERN int32 HEADR;
+EXTERN int32 HEADTYPE;
+EXTERN int32 INITRND;
+EXTERN int64 INITTEXT;
+EXTERN int64 INITDAT;
+EXTERN char* INITENTRY; /* entry point */
+EXTERN char* noname;
+EXTERN char* paramspace;
+EXTERN int nerrors;
-enum
-{
- LinkAuto = 0,
- LinkInternal,
- LinkExternal,
-};
EXTERN int linkmode;
+EXTERN int64 liveness;
-// for dynexport field of Sym
+// for dynexport field of LSym
enum
{
CgoExportDynamic = 1<<0,
@@ -190,119 +112,6 @@ EXTERN Segment segrodata;
EXTERN Segment segdata;
EXTERN Segment segdwarf;
-void setlinkmode(char*);
-void addlib(char *src, char *obj);
-void addlibpath(char *srcref, char *objref, char *file, char *pkg);
-Section* addsection(Segment*, char*, int);
-void copyhistfrog(char *buf, int nbuf);
-void addhist(int32 line, int type);
-void savehist(int32 line, int32 off);
-Hist* gethist(void);
-void getline(Hist*, int32 line, int32 *f, int32 *l);
-void asmlc(void);
-void histtoauto(void);
-void collapsefrog(Sym *s);
-Sym* newsym(char *symb, int v);
-Sym* lookup(char *symb, int v);
-Sym* rlookup(char *symb, int v);
-void nuxiinit(void);
-int find1(int32 l, int c);
-int find2(int32 l, int c);
-int32 ieeedtof(Ieee *e);
-double ieeedtod(Ieee *e);
-void undefsym(Sym *s);
-void zerosig(char *sp);
-void readundefs(char *f, int t);
-void loadlib(void);
-void errorexit(void);
-void mangle(char*);
-void objfile(char *file, char *pkg);
-void libinit(void);
-void pclntab(void);
-void symtab(void);
-void Lflag(char *arg);
-void usage(void);
-void adddynrel(Sym*, Reloc*);
-void adddynrela(Sym*, Sym*, Reloc*);
-void ldobj1(Biobuf *f, char*, int64 len, char *pn);
-void ldobj(Biobuf*, char*, int64, char*, char*, int);
-void ldelf(Biobuf*, char*, int64, char*);
-void ldmacho(Biobuf*, char*, int64, char*);
-void ldpe(Biobuf*, char*, int64, char*);
-void ldpkg(Biobuf*, char*, int64, char*, int);
-void mark(Sym *s);
-void mkfwd(void);
-char* expandpkg(char*, char*);
-void deadcode(void);
-Reloc* addrel(Sym*);
-void codeblk(int32, int32);
-void datblk(int32, int32);
-void reloc(void);
-void relocsym(Sym*);
-void savedata(Sym*, Prog*, char*);
-void symgrow(Sym*, int32);
-void addstrdata(char*, char*);
-vlong addstring(Sym*, char*);
-vlong adduint8(Sym*, uint8);
-vlong adduint16(Sym*, uint16);
-vlong adduint32(Sym*, uint32);
-vlong adduint64(Sym*, uint64);
-vlong adduintxx(Sym*, uint64, int);
-vlong addaddr(Sym*, Sym*);
-vlong addaddrplus(Sym*, Sym*, vlong);
-vlong addpcrelplus(Sym*, Sym*, vlong);
-vlong addsize(Sym*, Sym*);
-vlong setaddrplus(Sym*, vlong, Sym*, vlong);
-vlong setaddr(Sym*, vlong, Sym*);
-vlong setuint8(Sym*, vlong, uint8);
-vlong setuint16(Sym*, vlong, uint16);
-vlong setuint32(Sym*, vlong, uint32);
-vlong setuint64(Sym*, vlong, uint64);
-vlong setuintxx(Sym*, vlong, uint64, vlong);
-void asmsym(void);
-void asmelfsym(void);
-void asmplan9sym(void);
-void putelfsectionsym(Sym*, int);
-void putelfsymshndx(vlong, int);
-void strnput(char*, int);
-void dodata(void);
-void dosymtype(void);
-void address(void);
-void textaddress(void);
-void genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*));
-vlong datoff(vlong);
-void adddynlib(char*);
-int archreloc(Reloc*, Sym*, vlong*);
-void adddynsym(Sym*);
-void addexport(void);
-void dostkcheck(void);
-void undef(void);
-void doweak(void);
-void setpersrc(Sym*);
-void doversion(void);
-void usage(void);
-void setinterp(char*);
-Sym* listsort(Sym*, int(*cmp)(Sym*, Sym*), int);
-int valuecmp(Sym*, Sym*);
-void hostobjs(void);
-void hostlink(void);
-char* estrdup(char*);
-void* erealloc(void*, long);
-Sym* defgostring(char*);
-
-int pathchar(void);
-void* mal(uint32);
-void unmal(void*, uint32);
-void mywhatsys(void);
-int rbyoff(const void*, const void*);
-
-uint16 le16(uchar*);
-uint32 le32(uchar*);
-uint64 le64(uchar*);
-uint16 be16(uchar*);
-uint32 be32(uchar*);
-uint64 be64(uchar*);
-
typedef struct Endian Endian;
struct Endian
{
@@ -325,28 +134,6 @@ enum {
Pkgdef
};
-/* executable header types */
-enum {
- Hgarbunix = 0, // garbage unix
- Hnoheader, // no header
- Hunixcoff, // unix coff
- Hrisc, // aif for risc os
- Hplan9x32, // plan 9 32-bit format
- Hplan9x64, // plan 9 64-bit format
- Hmsdoscom, // MS-DOS .COM
- Hnetbsd, // NetBSD
- Hmsdosexe, // fake MS-DOS .EXE
- Hixp1200, // IXP1200 (raw)
- Helf, // ELF32
- Hipaq, // ipaq
- Hdarwin, // Apple Mach-O
- Hlinux, // Linux ELF
- Hfreebsd, // FreeBSD ELF
- Hwindows, // MS Windows PE
- Hopenbsd, // OpenBSD ELF
- Hdragonfly, // DragonFly ELF
-};
-
typedef struct Header Header;
struct Header {
char *name;
@@ -356,14 +143,9 @@ struct Header {
EXTERN char* headstring;
extern Header headers[];
-int headtype(char*);
-char* headstr(int);
-void setheadtype(char*);
-
-int Yconv(Fmt*);
-
-#pragma varargck type "O" int
-#pragma varargck type "Y" Sym*
+#pragma varargck type "Y" LSym*
+#pragma varargck type "Z" char*
+#pragma varargck type "i" char*
// buffered output
@@ -383,29 +165,117 @@ EXTERN char* cbpmax;
if(--cbc <= 0)\
cflush(); }
+void Lflag(char *arg);
+int Yconv(Fmt *fp);
+int Zconv(Fmt *fp);
+void addexport(void);
+void address(void);
+Section*addsection(Segment *seg, char *name, int rwx);
+void addstrdata(char *name, char *value);
+vlong addstring(LSym *s, char *str);
+void asmelfsym(void);
+void asmplan9sym(void);
+uint16 be16(uchar *b);
+uint32 be32(uchar *b);
+uint64 be64(uchar *b);
+void callgraph(void);
void cflush(void);
+void codeblk(int32 addr, int32 size);
vlong cpos(void);
-void cseek(vlong);
-void cwrite(void*, int);
+void cseek(vlong p);
+void cwrite(void *buf, int n);
+void datblk(int32 addr, int32 size);
+int datcmp(LSym *s1, LSym *s2);
+vlong datoff(vlong addr);
+void deadcode(void);
+LSym* decodetype_arrayelem(LSym *s);
+vlong decodetype_arraylen(LSym *s);
+LSym* decodetype_chanelem(LSym *s);
+int decodetype_funcdotdotdot(LSym *s);
+int decodetype_funcincount(LSym *s);
+LSym* decodetype_funcintype(LSym *s, int i);
+int decodetype_funcoutcount(LSym *s);
+LSym* decodetype_funcouttype(LSym *s, int i);
+LSym* decodetype_gc(LSym *s);
+vlong decodetype_ifacemethodcount(LSym *s);
+uint8 decodetype_kind(LSym *s);
+LSym* decodetype_mapkey(LSym *s);
+LSym* decodetype_mapvalue(LSym *s);
+LSym* decodetype_ptrelem(LSym *s);
+vlong decodetype_size(LSym *s);
+int decodetype_structfieldcount(LSym *s);
+char* decodetype_structfieldname(LSym *s, int i);
+vlong decodetype_structfieldoffs(LSym *s, int i);
+LSym* decodetype_structfieldtype(LSym *s, int i);
+void dodata(void);
+void dostkcheck(void);
+void dostkoff(void);
+void dosymtype(void);
+void doversion(void);
+void doweak(void);
+void dynreloc(void);
+void dynrelocsym(LSym *s);
+vlong entryvalue(void);
+void errorexit(void);
+void follow(void);
+void genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*));
+void growdatsize(vlong *datsizep, LSym *s);
+char* headstr(int v);
+int headtype(char *name);
+void hostlink(void);
+void hostobjs(void);
+int iconv(Fmt *fp);
void importcycles(void);
-int Zconv(Fmt*);
+void linkarchinit(void);
+void ldelf(Biobuf *f, char *pkg, int64 len, char *pn);
+void ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 len, char *pn, char *file);
+void ldmacho(Biobuf *f, char *pkg, int64 len, char *pn);
+void ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence);
+void ldpe(Biobuf *f, char *pkg, int64 len, char *pn);
+void ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence);
+uint16 le16(uchar *b);
+uint32 le32(uchar *b);
+uint64 le64(uchar *b);
+void libinit(void);
+LSym* listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off);
+void loadinternal(char *name);
+void loadlib(void);
+void lputb(int32 l);
+void lputl(int32 l);
+void* mal(uint32 n);
+void mark(LSym *s);
+void mywhatsys(void);
+struct ar_hdr;
+void objfile(char *file, char *pkg);
+void patch(void);
+int pathchar(void);
+void pcln(void);
+void pclntab(void);
+void putelfsectionsym(LSym* s, int shndx);
+void putelfsymshndx(vlong sympos, int shndx);
+void putsymb(LSym *s, char *name, int t, vlong v, vlong size, int ver, LSym *typ);
+int rbyoff(const void *va, const void *vb);
+void reloc(void);
+void relocsym(LSym *s);
+void setheadtype(char *s);
+void setinterp(char *s);
+void setlinkmode(char *arg);
+void span(void);
+void strnput(char *s, int n);
+vlong symaddr(LSym *s);
+void symtab(void);
+void textaddress(void);
+void undef(void);
+void unmal(void *v, uint32 n);
+void usage(void);
+void vputb(uint64 v);
+int valuecmp(LSym *a, LSym *b);
+void vputl(uint64 v);
+void wputb(ushort w);
+void wputl(ushort w);
+void xdefine(char *p, int t, vlong v);
+void zerosig(char *sp);
+void archinit(void);
+void diag(char *fmt, ...);
-uint8 decodetype_kind(Sym*);
-vlong decodetype_size(Sym*);
-Sym* decodetype_gc(Sym*);
-Sym* decodetype_arrayelem(Sym*);
-vlong decodetype_arraylen(Sym*);
-Sym* decodetype_ptrelem(Sym*);
-Sym* decodetype_mapkey(Sym*);
-Sym* decodetype_mapvalue(Sym*);
-Sym* decodetype_chanelem(Sym*);
-int decodetype_funcdotdotdot(Sym*);
-int decodetype_funcincount(Sym*);
-int decodetype_funcoutcount(Sym*);
-Sym* decodetype_funcintype(Sym*, int);
-Sym* decodetype_funcouttype(Sym*, int);
-int decodetype_structfieldcount(Sym*);
-char* decodetype_structfieldname(Sym*, int);
-Sym* decodetype_structfieldtype(Sym*, int);
-vlong decodetype_structfieldoffs(Sym*, int);
-vlong decodetype_ifacemethodcount(Sym*);
+#pragma varargck argpos diag 1
diff --git a/src/cmd/ld/macho.c b/src/cmd/ld/macho.c
index d135a92da..61306bb7c 100644
--- a/src/cmd/ld/macho.c
+++ b/src/cmd/ld/macho.c
@@ -25,7 +25,7 @@ enum
};
static int nkind[NumSymKind];
-static Sym** sortsym;
+static LSym** sortsym;
static int nsortsym;
// Amount of space left for adding load commands
@@ -232,37 +232,37 @@ machowrite(void)
void
domacho(void)
{
- Sym *s;
+ LSym *s;
if(debug['d'])
return;
// empirically, string table must begin with " \x00".
- s = lookup(".machosymstr", 0);
+ s = linklookup(ctxt, ".machosymstr", 0);
s->type = SMACHOSYMSTR;
s->reachable = 1;
- adduint8(s, ' ');
- adduint8(s, '\0');
+ adduint8(ctxt, s, ' ');
+ adduint8(ctxt, s, '\0');
- s = lookup(".machosymtab", 0);
+ s = linklookup(ctxt, ".machosymtab", 0);
s->type = SMACHOSYMTAB;
s->reachable = 1;
if(linkmode != LinkExternal) {
- s = lookup(".plt", 0); // will be __symbol_stub
+ s = linklookup(ctxt, ".plt", 0); // will be __symbol_stub
s->type = SMACHOPLT;
s->reachable = 1;
- s = lookup(".got", 0); // will be __nl_symbol_ptr
+ s = linklookup(ctxt, ".got", 0); // will be __nl_symbol_ptr
s->type = SMACHOGOT;
s->reachable = 1;
s->align = 4;
- s = lookup(".linkedit.plt", 0); // indirect table for .plt
+ s = linklookup(ctxt, ".linkedit.plt", 0); // indirect table for .plt
s->type = SMACHOINDIRECTPLT;
s->reachable = 1;
- s = lookup(".linkedit.got", 0); // indirect table for .got
+ s = linklookup(ctxt, ".linkedit.got", 0); // indirect table for .got
s->type = SMACHOINDIRECTGOT;
s->reachable = 1;
}
@@ -334,7 +334,7 @@ machoshbits(MachoSeg *mseg, Section *sect, char *segname)
if(strcmp(sect->name, ".got") == 0) {
msect->name = "__nl_symbol_ptr";
msect->flag = 6; /* section with nonlazy symbol pointers */
- msect->res1 = lookup(".linkedit.plt", 0)->size / 4; /* offset into indirect symbol table */
+ msect->res1 = linklookup(ctxt, ".linkedit.plt", 0)->size / 4; /* offset into indirect symbol table */
}
}
@@ -432,13 +432,13 @@ asmbmacho(void)
}
if(!debug['d']) {
- Sym *s1, *s2, *s3, *s4;
+ LSym *s1, *s2, *s3, *s4;
// must match domacholink below
- s1 = lookup(".machosymtab", 0);
- s2 = lookup(".linkedit.plt", 0);
- s3 = lookup(".linkedit.got", 0);
- s4 = lookup(".machosymstr", 0);
+ s1 = linklookup(ctxt, ".machosymtab", 0);
+ s2 = linklookup(ctxt, ".linkedit.plt", 0);
+ s3 = linklookup(ctxt, ".linkedit.got", 0);
+ s4 = linklookup(ctxt, ".machosymstr", 0);
if(linkmode != LinkExternal) {
ms = newMachoSeg("__LINKEDIT", 0);
@@ -484,7 +484,7 @@ asmbmacho(void)
}
static int
-symkind(Sym *s)
+symkind(LSym *s)
{
if(s->type == SDYNIMPORT)
return SymKindUndef;
@@ -494,7 +494,7 @@ symkind(Sym *s)
}
static void
-addsym(Sym *s, char *name, int type, vlong addr, vlong size, int ver, Sym *gotype)
+addsym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *gotype)
{
USED(name);
USED(addr);
@@ -524,11 +524,11 @@ addsym(Sym *s, char *name, int type, vlong addr, vlong size, int ver, Sym *gotyp
static int
scmp(const void *p1, const void *p2)
{
- Sym *s1, *s2;
+ LSym *s1, *s2;
int k1, k2;
- s1 = *(Sym**)p1;
- s2 = *(Sym**)p2;
+ s1 = *(LSym**)p1;
+ s2 = *(LSym**)p2;
k1 = symkind(s1);
k2 = symkind(s2);
@@ -539,12 +539,12 @@ scmp(const void *p1, const void *p2)
}
static void
-machogenasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
+machogenasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
{
- Sym *s;
+ LSym *s;
genasmsym(put);
- for(s=allsym; s; s=s->allsym)
+ for(s=ctxt->allsym; s; s=s->allsym)
if(s->type == SDYNIMPORT || s->type == SHOSTOBJ)
if(s->reachable)
put(s, nil, 'D', 0, 0, 0, nil);
@@ -573,39 +573,54 @@ static void
machosymtab(void)
{
int i;
- Sym *symtab, *symstr, *s, *o;
+ LSym *symtab, *symstr, *s, *o;
+ char *p;
- symtab = lookup(".machosymtab", 0);
- symstr = lookup(".machosymstr", 0);
+ symtab = linklookup(ctxt, ".machosymtab", 0);
+ symstr = linklookup(ctxt, ".machosymstr", 0);
for(i=0; i<nsortsym; i++) {
s = sortsym[i];
- adduint32(symtab, symstr->size);
+ adduint32(ctxt, symtab, symstr->size);
// Only add _ to C symbols. Go symbols have dot in the name.
if(strstr(s->extname, ".") == nil)
- adduint8(symstr, '_');
- addstring(symstr, s->extname);
+ adduint8(ctxt, symstr, '_');
+ // replace "·" as ".", because DTrace cannot handle it.
+ if(strstr(s->extname, "·") == nil) {
+ addstring(symstr, s->extname);
+ } else {
+ p = s->extname;
+ while (*p++ != '\0') {
+ if((uchar)*p == 0xc2 && (uchar)*(p+1) == 0xb7) {
+ adduint8(ctxt, symstr, '.');
+ p++;
+ } else {
+ adduint8(ctxt, symstr, *p);
+ }
+ }
+ adduint8(ctxt, symstr, '\0');
+ }
if(s->type == SDYNIMPORT || s->type == SHOSTOBJ) {
- adduint8(symtab, 0x01); // type N_EXT, external symbol
- adduint8(symtab, 0); // no section
- adduint16(symtab, 0); // desc
- adduintxx(symtab, 0, PtrSize); // no value
+ adduint8(ctxt, symtab, 0x01); // type N_EXT, external symbol
+ adduint8(ctxt, symtab, 0); // no section
+ adduint16(ctxt, symtab, 0); // desc
+ adduintxx(ctxt, symtab, 0, PtrSize); // no value
} else {
if(s->cgoexport)
- adduint8(symtab, 0x0f);
+ adduint8(ctxt, symtab, 0x0f);
else
- adduint8(symtab, 0x0e);
+ adduint8(ctxt, symtab, 0x0e);
o = s;
while(o->outer != nil)
o = o->outer;
if(o->sect == nil) {
diag("missing section for %s", s->name);
- adduint8(symtab, 0);
+ adduint8(ctxt, symtab, 0);
} else
- adduint8(symtab, o->sect->extnum);
- adduint16(symtab, 0); // desc
- adduintxx(symtab, symaddr(s), PtrSize);
+ adduint8(ctxt, symtab, o->sect->extnum);
+ adduint16(ctxt, symtab, 0); // desc
+ adduintxx(ctxt, symtab, symaddr(s), PtrSize);
}
}
}
@@ -615,7 +630,7 @@ machodysymtab(void)
{
int n;
MachoLoad *ml;
- Sym *s1, *s2, *s3;
+ LSym *s1, *s2, *s3;
ml = newMachoLoad(11, 18); /* LC_DYSYMTAB */
@@ -639,9 +654,9 @@ machodysymtab(void)
ml->data[11] = 0; /* nextrefsyms */
// must match domacholink below
- s1 = lookup(".machosymtab", 0);
- s2 = lookup(".linkedit.plt", 0);
- s3 = lookup(".linkedit.got", 0);
+ s1 = linklookup(ctxt, ".machosymtab", 0);
+ s2 = linklookup(ctxt, ".linkedit.plt", 0);
+ s3 = linklookup(ctxt, ".linkedit.got", 0);
ml->data[12] = linkoff + s1->size; /* indirectsymoff */
ml->data[13] = (s2->size + s3->size) / 4; /* nindirectsyms */
@@ -655,15 +670,15 @@ vlong
domacholink(void)
{
int size;
- Sym *s1, *s2, *s3, *s4;
+ LSym *s1, *s2, *s3, *s4;
machosymtab();
// write data that will be linkedit section
- s1 = lookup(".machosymtab", 0);
- s2 = lookup(".linkedit.plt", 0);
- s3 = lookup(".linkedit.got", 0);
- s4 = lookup(".machosymstr", 0);
+ s1 = linklookup(ctxt, ".machosymtab", 0);
+ s2 = linklookup(ctxt, ".linkedit.plt", 0);
+ s3 = linklookup(ctxt, ".linkedit.got", 0);
+ s4 = linklookup(ctxt, ".machosymstr", 0);
// Force the linkedit section to end on a 16-byte
// boundary. This allows pure (non-cgo) Go binaries
@@ -683,7 +698,7 @@ domacholink(void)
// any alignment padding itself, working around the
// issue.
while(s4->size%16)
- adduint8(s4, 0);
+ adduint8(ctxt, s4, 0);
size = s1->size + s2->size + s3->size + s4->size;
@@ -702,9 +717,9 @@ domacholink(void)
void
-machorelocsect(Section *sect, Sym *first)
+machorelocsect(Section *sect, LSym *first)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr;
Reloc *r;
@@ -726,7 +741,7 @@ machorelocsect(Section *sect, Sym *first)
continue;
if(sym->value >= eaddr)
break;
- cursym = sym;
+ ctxt->cursym = sym;
for(r = sym->r; r < sym->r+sym->nr; r++) {
if(r->done)
@@ -747,7 +762,7 @@ machoemitreloc(void)
while(cpos()&7)
cput(0);
- machorelocsect(segtext.sect, textp);
+ machorelocsect(segtext.sect, ctxt->textp);
for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
machorelocsect(sect, datap);
for(sect=segdata.sect; sect!=nil; sect=sect->next)
diff --git a/src/cmd/ld/pass.c b/src/cmd/ld/pass.c
new file mode 100644
index 000000000..788b7c75a
--- /dev/null
+++ b/src/cmd/ld/pass.c
@@ -0,0 +1,104 @@
+// 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 "l.h"
+#include "../ld/lib.h"
+#include "../../pkg/runtime/stack.h"
+
+void
+follow(void)
+{
+ LSym *s;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f follow\n", cputime());
+ Bflush(&bso);
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->follow(ctxt, s);
+}
+
+void
+patch(void)
+{
+ LSym *s;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f mkfwd\n", cputime());
+ Bflush(&bso);
+ for(s = ctxt->textp; s != nil; s = s->next)
+ mkfwd(s);
+ if(debug['v'])
+ Bprint(&bso, "%5.2f patch\n", cputime());
+ Bflush(&bso);
+
+ if(flag_shared) {
+ s = linklookup(ctxt, "init_array", 0);
+ s->type = SINITARR;
+ s->reachable = 1;
+ s->hide = 1;
+ addaddr(ctxt, s, linklookup(ctxt, INITENTRY, 0));
+ }
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ linkpatch(ctxt, s);
+}
+
+void
+dostkoff(void)
+{
+ LSym *s;
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->addstacksplit(ctxt, s);
+}
+
+void
+span(void)
+{
+ LSym *s;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f span\n", cputime());
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->assemble(ctxt, s);
+}
+
+void
+pcln(void)
+{
+ LSym *s;
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ linkpcln(ctxt, s);
+}
diff --git a/src/cmd/ld/pcln.c b/src/cmd/ld/pcln.c
new file mode 100644
index 000000000..4c2ffa78e
--- /dev/null
+++ b/src/cmd/ld/pcln.c
@@ -0,0 +1,244 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "l.h"
+#include "lib.h"
+#include "../../pkg/runtime/funcdata.h"
+
+static void
+addvarint(Pcdata *d, uint32 val)
+{
+ int32 n;
+ uint32 v;
+ uchar *p;
+
+ 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;
+}
+
+static int32
+addpctab(LSym *ftab, int32 off, Pcdata *d)
+{
+ int32 start;
+
+ start = ftab->np;
+ symgrow(ctxt, ftab, start + d->n);
+ memmove(ftab->p + start, d->p, d->n);
+
+ return setuint32(ctxt, ftab, off, start);
+}
+
+static int32
+ftabaddstring(LSym *ftab, char *s)
+{
+ int32 n, start;
+
+ n = strlen(s)+1;
+ start = ftab->np;
+ symgrow(ctxt, ftab, start+n+1);
+ strcpy((char*)ftab->p + start, s);
+ return start;
+}
+
+static void
+renumberfiles(Link *ctxt, LSym **files, int nfiles, Pcdata *d)
+{
+ int i;
+ LSym *f;
+ Pcdata out;
+ Pciter it;
+ uint32 v;
+ int32 oldval, newval, val, dv;
+
+ // Give files numbers.
+ for(i=0; i<nfiles; i++) {
+ f = files[i];
+ if(f->type != SFILEPATH) {
+ f->value = ++ctxt->nhistfile;
+ f->type = SFILEPATH;
+ f->next = ctxt->filesyms;
+ ctxt->filesyms = f;
+ }
+ }
+
+ newval = -1;
+ memset(&out, 0, sizeof out);
+
+ for(pciterinit(ctxt, &it, d); !it.done; pciternext(&it)) {
+ // value delta
+ oldval = it.value;
+ if(oldval == -1)
+ val = -1;
+ else {
+ if(oldval < 0 || oldval >= nfiles)
+ sysfatal("bad pcdata %d", oldval);
+ val = files[oldval]->value;
+ }
+ dv = val - newval;
+ newval = val;
+ v = (uint32)(dv<<1) ^ (uint32)(int32)(dv>>31);
+ addvarint(&out, v);
+
+ // pc delta
+ addvarint(&out, (it.nextpc - it.pc) / it.pcscale);
+ }
+
+ // terminating value delta
+ addvarint(&out, 0);
+
+ free(d->p);
+ *d = out;
+}
+
+
+// pclntab initializes the pclntab symbol with
+// runtime function and file name information.
+void
+pclntab(void)
+{
+ int32 i, nfunc, start, funcstart;
+ LSym *ftab, *s;
+ int32 off, end, frameptrsize;
+ int64 funcdata_bytes;
+ Pcln *pcln;
+ Pciter it;
+ static Pcln zpcln;
+
+ funcdata_bytes = 0;
+ ftab = linklookup(ctxt, "pclntab", 0);
+ ftab->type = SPCLNTAB;
+ ftab->reachable = 1;
+
+ // See golang.org/s/go12symtab for the format. Briefly:
+ // 8-byte header
+ // nfunc [PtrSize bytes]
+ // function table, alternating PC and offset to func struct [each entry PtrSize bytes]
+ // end PC [PtrSize bytes]
+ // offset to file table [4 bytes]
+ nfunc = 0;
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next)
+ nfunc++;
+ symgrow(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize+4);
+ setuint32(ctxt, ftab, 0, 0xfffffffb);
+ setuint8(ctxt, ftab, 6, MINLC);
+ setuint8(ctxt, ftab, 7, PtrSize);
+ setuintxx(ctxt, ftab, 8, nfunc, PtrSize);
+
+ nfunc = 0;
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next, nfunc++) {
+ pcln = ctxt->cursym->pcln;
+ if(pcln == nil)
+ pcln = &zpcln;
+
+ funcstart = ftab->np;
+ funcstart += -ftab->np & (PtrSize-1);
+
+ setaddr(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize, ctxt->cursym);
+ setuintxx(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, funcstart, PtrSize);
+
+ // fixed size of struct, checked below
+ off = funcstart;
+ end = funcstart + PtrSize + 3*4 + 5*4 + pcln->npcdata*4 + pcln->nfuncdata*PtrSize;
+ if(pcln->nfuncdata > 0 && (end&(PtrSize-1)))
+ end += 4;
+ symgrow(ctxt, ftab, end);
+
+ // entry uintptr
+ off = setaddr(ctxt, ftab, off, ctxt->cursym);
+
+ // name int32
+ off = setuint32(ctxt, ftab, off, ftabaddstring(ftab, ctxt->cursym->name));
+
+ // args int32
+ // TODO: Move into funcinfo.
+ off = setuint32(ctxt, ftab, off, ctxt->cursym->args);
+
+ // frame int32
+ // TODO: Remove entirely. The pcsp table is more precise.
+ // This is only used by a fallback case during stack walking
+ // when a called function doesn't have argument information.
+ // We need to make sure everything has argument information
+ // and then remove this.
+ frameptrsize = PtrSize;
+ if(ctxt->cursym->leaf)
+ frameptrsize = 0;
+ off = setuint32(ctxt, ftab, off, ctxt->cursym->locals + frameptrsize);
+
+ if(pcln != &zpcln) {
+ renumberfiles(ctxt, pcln->file, pcln->nfile, &pcln->pcfile);
+ if(0) {
+ // Sanity check the new numbering
+ for(pciterinit(ctxt, &it, &pcln->pcfile); !it.done; pciternext(&it)) {
+ if(it.value < 1 || it.value > ctxt->nhistfile) {
+ diag("bad file number in pcfile: %d not in range [1, %d]\n", it.value, ctxt->nhistfile);
+ errorexit();
+ }
+ }
+ }
+ }
+
+ // pcdata
+ off = addpctab(ftab, off, &pcln->pcsp);
+ off = addpctab(ftab, off, &pcln->pcfile);
+ off = addpctab(ftab, off, &pcln->pcline);
+ off = setuint32(ctxt, ftab, off, pcln->npcdata);
+ off = setuint32(ctxt, ftab, off, pcln->nfuncdata);
+ for(i=0; i<pcln->npcdata; i++)
+ off = addpctab(ftab, off, &pcln->pcdata[i]);
+
+ // funcdata, must be pointer-aligned and we're only int32-aligned.
+ // Missing funcdata will be 0 (nil pointer).
+ if(pcln->nfuncdata > 0) {
+ if(off&(PtrSize-1))
+ off += 4;
+ for(i=0; i<pcln->nfuncdata; i++) {
+ if(pcln->funcdata[i] == nil)
+ setuintxx(ctxt, ftab, off+PtrSize*i, pcln->funcdataoff[i], PtrSize);
+ else {
+ // TODO: Dedup.
+ funcdata_bytes += pcln->funcdata[i]->size;
+ setaddrplus(ctxt, ftab, off+PtrSize*i, pcln->funcdata[i], pcln->funcdataoff[i]);
+ }
+ }
+ off += pcln->nfuncdata*PtrSize;
+ }
+
+ if(off != end) {
+ diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, pcln->npcdata, pcln->nfuncdata, PtrSize);
+ errorexit();
+ }
+
+ // Final entry of table is just end pc.
+ if(ctxt->cursym->next == nil)
+ setaddrplus(ctxt, ftab, 8+PtrSize+(nfunc+1)*2*PtrSize, ctxt->cursym, ctxt->cursym->size);
+ }
+
+ // Start file table.
+ start = ftab->np;
+ start += -ftab->np & (PtrSize-1);
+ setuint32(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, start);
+
+ symgrow(ctxt, ftab, start+(ctxt->nhistfile+1)*4);
+ setuint32(ctxt, ftab, start, ctxt->nhistfile);
+ for(s = ctxt->filesyms; s != S; s = s->next)
+ setuint32(ctxt, ftab, start + s->value*4, ftabaddstring(ftab, s->name));
+
+ ftab->size = ftab->np;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
+}
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index 7b9a596fc..c26cd5264 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -32,15 +32,11 @@ static char dosstub[] =
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-// Note: currently only up to 8 chars plus \0.
-static char *symlabels[] = {
- "symtab", "esymtab", "pclntab", "epclntab"
-};
-
-static Sym *rsrcsym;
+static LSym *rsrcsym;
-static char symnames[256];
-static int nextsymoff;
+static char* strtbl;
+static int strtblnextoff;
+static int strtblsize;
int32 PESECTHEADR;
int32 PEFILEHEADR;
@@ -50,6 +46,7 @@ static int nsect;
static int nextsectoff;
static int nextfileoff;
static int textsect;
+static int datasect;
static IMAGE_FILE_HEADER fh;
static IMAGE_OPTIONAL_HEADER oh;
@@ -62,7 +59,7 @@ static IMAGE_DATA_DIRECTORY* dd;
typedef struct Imp Imp;
struct Imp {
- Sym* s;
+ LSym* s;
uvlong off;
Imp* next;
};
@@ -78,9 +75,21 @@ struct Dll {
static Dll* dr;
-static Sym *dexport[1024];
+static LSym *dexport[1024];
static int nexport;
+typedef struct COFFSym COFFSym;
+struct COFFSym
+{
+ LSym* sym;
+ int strtbloff;
+ int sect;
+ vlong value;
+};
+
+static COFFSym* coffsym;
+static int ncoffsym;
+
static IMAGE_SECTION_HEADER*
addpesection(char *name, int sectsize, int filesize)
{
@@ -191,11 +200,11 @@ initdynimport(void)
{
Imp *m;
Dll *d;
- Sym *s, *dynamic;
+ LSym *s, *dynamic;
dr = nil;
m = nil;
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(!s->reachable || s->type != SDYNIMPORT)
continue;
for(d = dr; d != nil; d = d->next) {
@@ -216,7 +225,7 @@ initdynimport(void)
d->ms = m;
}
- dynamic = lookup(".windynamic", 0);
+ dynamic = linklookup(ctxt, ".windynamic", 0);
dynamic->reachable = 1;
dynamic->type = SWINDOWS;
for(d = dr; d != nil; d = d->next) {
@@ -241,10 +250,10 @@ addimports(IMAGE_SECTION_HEADER *datsect)
vlong startoff, endoff;
Imp *m;
Dll *d;
- Sym* dynamic;
+ LSym* dynamic;
startoff = cpos();
- dynamic = lookup(".windynamic", 0);
+ dynamic = linklookup(ctxt, ".windynamic", 0);
// skip import descriptor table (will write it later)
n = 0;
@@ -322,20 +331,20 @@ addimports(IMAGE_SECTION_HEADER *datsect)
static int
scmp(const void *p1, const void *p2)
{
- Sym *s1, *s2;
+ LSym *s1, *s2;
- s1 = *(Sym**)p1;
- s2 = *(Sym**)p2;
+ s1 = *(LSym**)p1;
+ s2 = *(LSym**)p2;
return strcmp(s1->extname, s2->extname);
}
static void
initdynexport(void)
{
- Sym *s;
+ LSym *s;
nexport = 0;
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(!s->reachable || !(s->cgoexport & CgoExportDynamic))
continue;
if(nexport+1 > sizeof(dexport)/sizeof(dexport[0])) {
@@ -410,10 +419,10 @@ addexports(void)
void
dope(void)
{
- Sym *rel;
+ LSym *rel;
/* relocation table */
- rel = lookup(".rel", 0);
+ rel = linklookup(ctxt, ".rel", 0);
rel->reachable = 1;
rel->type = SELFROSECT;
@@ -421,6 +430,24 @@ dope(void)
initdynexport();
}
+static int
+strtbladd(char *name)
+{
+ int newsize, thisoff;
+
+ newsize = strtblnextoff + strlen(name) + 1;
+ if(newsize > strtblsize) {
+ strtblsize = 2 * (newsize + (1<<18));
+ strtbl = realloc(strtbl, strtblsize);
+ }
+ thisoff = strtblnextoff+4; // first string starts at offset=4
+ strcpy(&strtbl[strtblnextoff], name);
+ strtblnextoff += strlen(name);
+ strtbl[strtblnextoff] = 0;
+ strtblnextoff++;
+ return thisoff;
+}
+
/*
* For more than 8 characters section names, name contains a slash (/) that is
* followed by an ASCII representation of a decimal number that is an offset into
@@ -433,20 +460,13 @@ newPEDWARFSection(char *name, vlong size)
{
IMAGE_SECTION_HEADER *h;
char s[8];
+ int off;
if(size == 0)
return nil;
- if(nextsymoff+strlen(name)+1 > sizeof(symnames)) {
- diag("pe string table is full");
- errorexit();
- }
-
- strcpy(&symnames[nextsymoff], name);
- sprint(s, "/%d\0", nextsymoff+4);
- nextsymoff += strlen(name);
- symnames[nextsymoff] = 0;
- nextsymoff ++;
+ off = strtbladd(name);
+ sprint(s, "/%d\0", off);
h = addpesection(s, size, size);
h->Characteristics = IMAGE_SCN_MEM_READ|
IMAGE_SCN_MEM_DISCARDABLE;
@@ -455,40 +475,97 @@ newPEDWARFSection(char *name, vlong size)
}
static void
+addsym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *gotype)
+{
+ COFFSym *cs;
+ USED(name);
+ USED(addr);
+ USED(size);
+ USED(ver);
+ USED(gotype);
+
+ if(s == nil)
+ return;
+
+ if(s->sect == nil)
+ return;
+
+ switch(type) {
+ default:
+ return;
+ case 'D':
+ case 'B':
+ case 'T':
+ break;
+ }
+
+ if(coffsym) {
+ cs = &coffsym[ncoffsym];
+ cs->sym = s;
+ if(strlen(s->name) > 8)
+ cs->strtbloff = strtbladd(s->name);
+ if(s->value >= segdata.vaddr) {
+ cs->value = s->value - segdata.vaddr;
+ cs->sect = datasect;
+ } else if(s->value >= segtext.vaddr) {
+ cs->value = s->value - segtext.vaddr;
+ cs->sect = textsect;
+ } else {
+ cs->value = 0;
+ cs->sect = 0;
+ diag("addsym %#llx", addr);
+ }
+ }
+ ncoffsym++;
+}
+
+static void
addsymtable(void)
{
IMAGE_SECTION_HEADER *h;
int i, size;
- Sym *s;
-
- fh.NumberOfSymbols = sizeof(symlabels)/sizeof(symlabels[0]);
- size = nextsymoff + 4 + 18*fh.NumberOfSymbols;
+ COFFSym *s;
+
+ if(!debug['s']) {
+ genasmsym(addsym);
+ coffsym = mal(ncoffsym * sizeof coffsym[0]);
+ ncoffsym = 0;
+ genasmsym(addsym);
+ }
+
+ size = strtblnextoff + 4 + 18*ncoffsym;
h = addpesection(".symtab", size, size);
h->Characteristics = IMAGE_SCN_MEM_READ|
IMAGE_SCN_MEM_DISCARDABLE;
chksectoff(h, cpos());
fh.PointerToSymbolTable = cpos();
+ fh.NumberOfSymbols = ncoffsym;
// put COFF symbol table
- for (i=0; i<fh.NumberOfSymbols; i++) {
- s = rlookup(symlabels[i], 0);
- strnput(s->name, 8);
- lputl(datoff(s->value));
- wputl(textsect);
+ for (i=0; i<ncoffsym; i++) {
+ s = &coffsym[i];
+ if(s->strtbloff == 0)
+ strnput(s->sym->name, 8);
+ else {
+ lputl(0);
+ lputl(s->strtbloff);
+ }
+ lputl(s->value);
+ wputl(s->sect);
wputl(0x0308); // "array of structs"
cput(2); // storage class: external
cput(0); // no aux entries
}
// put COFF string table
- lputl(nextsymoff + 4);
- for (i=0; i<nextsymoff; i++)
- cput(symnames[i]);
+ lputl(strtblnextoff + 4);
+ for (i=0; i<strtblnextoff; i++)
+ cput(strtbl[i]);
strnput("", h->SizeOfRawData - size);
}
void
-setpersrc(Sym *sym)
+setpersrc(LSym *sym)
{
if(rsrcsym != nil)
diag("too many .rsrc sections");
@@ -529,49 +606,6 @@ addpersrc(void)
dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h->VirtualSize;
}
-static void
-addexcept(IMAGE_SECTION_HEADER *text)
-{
- IMAGE_SECTION_HEADER *pdata, *xdata;
- vlong startoff;
- uvlong n;
- Sym *sym;
-
- USED(text);
- if(thechar != '6')
- return;
-
- // write unwind info
- sym = lookup("runtime.sigtramp", 0);
- startoff = cpos();
- lputl(9); // version=1, flags=UNW_FLAG_EHANDLER, rest 0
- lputl(sym->value - PEBASE);
- lputl(0);
-
- n = cpos() - startoff;
- xdata = addpesection(".xdata", n, n);
- xdata->Characteristics = IMAGE_SCN_MEM_READ|
- IMAGE_SCN_CNT_INITIALIZED_DATA;
- chksectoff(xdata, startoff);
- strnput("", xdata->SizeOfRawData - n);
-
- // write a function table entry for the whole text segment
- startoff = cpos();
- lputl(text->VirtualAddress);
- lputl(text->VirtualAddress + text->VirtualSize);
- lputl(xdata->VirtualAddress);
-
- n = cpos() - startoff;
- pdata = addpesection(".pdata", n, n);
- pdata->Characteristics = IMAGE_SCN_MEM_READ|
- IMAGE_SCN_CNT_INITIALIZED_DATA;
- chksectoff(pdata, startoff);
- strnput("", pdata->SizeOfRawData - n);
-
- dd[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = pdata->VirtualAddress;
- dd[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = pdata->VirtualSize;
-}
-
void
asmbpe(void)
{
@@ -600,6 +634,7 @@ asmbpe(void)
d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
chksectseg(d, &segdata);
+ datasect = nsect;
if(!debug['s'])
dwarfaddpeheaders();
@@ -609,7 +644,6 @@ asmbpe(void)
addexports();
addsymtable();
addpersrc();
- addexcept(t);
fh.NumberOfSections = nsect;
fh.TimeDateStamp = time(0);
diff --git a/src/cmd/ld/pe.h b/src/cmd/ld/pe.h
index 7aa938829..03ed8d830 100644
--- a/src/cmd/ld/pe.h
+++ b/src/cmd/ld/pe.h
@@ -176,4 +176,4 @@ typedef struct {
IMAGE_DATA_DIRECTORY DataDirectory[16];
} PE64_IMAGE_OPTIONAL_HEADER;
-void setpersrc(Sym *sym);
+void setpersrc(LSym *sym);
diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c
new file mode 100644
index 000000000..819c37954
--- /dev/null
+++ b/src/cmd/ld/pobj.c
@@ -0,0 +1,197 @@
+// Inferno utils/6l/obj.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.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.
+
+// Reading object files.
+
+#define EXTERN
+#include "l.h"
+#include "../ld/lib.h"
+#include "../ld/elf.h"
+#include "../ld/macho.h"
+#include "../ld/dwarf.h"
+#include "../ld/pe.h"
+#include <ar.h>
+
+char *noname = "<none>";
+char* paramspace = "FP";
+
+void
+main(int argc, char *argv[])
+{
+ linkarchinit();
+ ctxt = linknew(thelinkarch);
+ ctxt->thechar = thechar;
+ ctxt->thestring = thestring;
+ ctxt->diag = diag;
+ ctxt->bso = &bso;
+
+ Binit(&bso, 1, OWRITE);
+ listinit();
+ memset(debug, 0, sizeof(debug));
+ nerrors = 0;
+ outfile = nil;
+ HEADTYPE = -1;
+ INITTEXT = -1;
+ INITDAT = -1;
+ INITRND = -1;
+ INITENTRY = 0;
+ linkmode = LinkAuto;
+ nuxiinit();
+
+ if(thechar == '5' && ctxt->goarm == 5)
+ debug['F'] = 1;
+
+ flagcount("1", "use alternate profiling code", &debug['1']);
+ if(thechar == '6')
+ flagcount("8", "assume 64-bit addresses", &debug['8']);
+ flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
+ flagint64("D", "addr: data address", &INITDAT);
+ flagstr("E", "sym: entry symbol", &INITENTRY);
+ if(thechar == '5')
+ flagcount("G", "debug pseudo-ops", &debug['G']);
+ flagfn1("I", "interp: set ELF interp", setinterp);
+ flagfn1("L", "dir: add dir to library path", Lflag);
+ flagfn1("H", "head: header type", setheadtype);
+ flagcount("K", "add stack underflow checks", &debug['K']);
+ if(thechar == '5')
+ flagcount("M", "disable software div/mod", &debug['M']);
+ flagcount("O", "print pc-line tables", &debug['O']);
+ flagcount("Q", "debug byte-register code gen", &debug['Q']);
+ if(thechar == '5')
+ flagcount("P", "debug code generation", &debug['P']);
+ flagint32("R", "rnd: address rounding", &INITRND);
+ flagcount("S", "check type signatures", &debug['S']);
+ flagint64("T", "addr: text address", &INITTEXT);
+ flagfn0("V", "print version and exit", doversion);
+ flagcount("W", "disassemble input", &debug['W']);
+ flagfn2("X", "name value: define string data", addstrdata);
+ flagcount("Z", "clear stack frame on entry", &debug['Z']);
+ flagcount("a", "disassemble output", &debug['a']);
+ flagcount("c", "dump call graph", &debug['c']);
+ flagcount("d", "disable dynamic executable", &debug['d']);
+ flagstr("extld", "linker to run in external mode", &extld);
+ flagstr("extldflags", "flags for external linker", &extldflags);
+ flagcount("f", "ignore version mismatch", &debug['f']);
+ flagcount("g", "disable go package data checks", &debug['g']);
+ flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
+ flagstr("k", "sym: set field tracking symbol", &tracksym);
+ flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
+ flagcount("n", "dump symbol table", &debug['n']);
+ flagstr("o", "outfile: set output file", &outfile);
+ flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
+ flagcount("race", "enable race detector", &flag_race);
+ flagcount("s", "disable symbol table", &debug['s']);
+ if(thechar == '5' || thechar == '6')
+ flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
+ flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
+ flagcount("u", "reject unsafe packages", &debug['u']);
+ flagcount("v", "print link trace", &debug['v']);
+ flagcount("w", "disable DWARF generation", &debug['w']);
+
+ 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)
+ usage();
+
+ if(outfile == nil) {
+ if(HEADTYPE == Hwindows)
+ outfile = smprint("%c.out.exe", thechar);
+ else
+ outfile = smprint("%c.out", thechar);
+ }
+ libinit(); // creates outfile
+
+ if(HEADTYPE == -1)
+ HEADTYPE = headtype(goos);
+ ctxt->headtype = HEADTYPE;
+ if (headstring == nil)
+ headstring = headstr(HEADTYPE);
+
+ archinit();
+ ctxt->debugfloat = debug['F'];
+
+ if(debug['v'])
+ Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n",
+ HEADTYPE, INITTEXT, INITDAT, INITRND);
+ Bflush(&bso);
+
+ cbp = buf.cbuf;
+ cbc = sizeof(buf.cbuf);
+
+ addlibpath(ctxt, "command line", "command line", argv[0], "main");
+ loadlib();
+
+ if(thechar == '5') {
+ // mark some functions that are only referenced after linker code editing
+ if(debug['F'])
+ mark(linkrlookup(ctxt, "_sfloat", 0));
+ mark(linklookup(ctxt, "runtime.read_tls_fallback", 0));
+ }
+
+ deadcode();
+ callgraph();
+ paramspace = "SP"; /* (FP) now (SP) on output */
+
+ doelf();
+ if(HEADTYPE == Hdarwin)
+ domacho();
+ dostkcheck();
+ if(HEADTYPE == Hwindows)
+ dope();
+ addexport();
+ textaddress();
+ pclntab();
+ symtab();
+ dodata();
+ address();
+ doweak();
+ reloc();
+ asmb();
+ undef();
+ hostlink();
+ 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);
+
+ errorexit();
+}
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index c9b4657f7..6d321c0bb 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -40,6 +40,7 @@ static int
putelfstr(char *s)
{
int off, n;
+ char *p, *q;
if(elfstrsize == 0 && s[0] != 0) {
// first entry must be empty string
@@ -54,6 +55,21 @@ putelfstr(char *s)
off = elfstrsize;
elfstrsize += n;
memmove(elfstrdat+off, s, n);
+ // replace "·" as ".", because DTrace cannot handle it.
+ p = strstr(s, "·");
+ if(p != nil) {
+ p = q = elfstrdat+off;
+ while (*q != '\0') {
+ if((uchar)*q == 0xc2 && (uchar)*(q+1) == 0xb7) {
+ q += 2;
+ *p++ = '.';
+ elfstrsize--;
+ } else {
+ *p++ = *q++;
+ }
+ }
+ *p = '\0';
+ }
return off;
}
@@ -86,10 +102,10 @@ static int numelfsym = 1; // 0 is reserved
static int elfbind;
static void
-putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
+putelfsym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
{
int bind, type, off;
- Sym *xo;
+ LSym *xo;
USED(go);
switch(t) {
@@ -109,12 +125,12 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
while(xo->outer != nil)
xo = xo->outer;
if(xo->sect == nil) {
- cursym = x;
+ ctxt->cursym = x;
diag("missing section in putelfsym");
return;
}
if(xo->sect->elfsect == nil) {
- cursym = x;
+ ctxt->cursym = x;
diag("missing ELF section in putelfsym");
return;
}
@@ -143,7 +159,7 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
}
void
-putelfsectionsym(Sym* s, int shndx)
+putelfsectionsym(LSym* s, int shndx)
{
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_SECTION, shndx, 0);
s->elfsym = numelfsym++;
@@ -170,7 +186,8 @@ putelfsymshndx(vlong sympos, int shndx)
void
asmelfsym(void)
{
- Sym *s;
+ LSym *s;
+ char *name;
// the first symbol entry is reserved
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
@@ -181,9 +198,9 @@ asmelfsym(void)
genasmsym(putelfsym);
if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) {
- s = lookup("runtime.tlsgm", 0);
+ s = linklookup(ctxt, "runtime.tlsgm", 0);
if(s->sect == nil) {
- cursym = nil;
+ ctxt->cursym = nil;
diag("missing section for %s", s->name);
errorexit();
}
@@ -195,16 +212,20 @@ asmelfsym(void)
elfglobalsymndx = numelfsym;
genasmsym(putelfsym);
- for(s=allsym; s!=S; s=s->allsym) {
- if(s->type != SHOSTOBJ)
+ for(s=ctxt->allsym; s!=S; s=s->allsym) {
+ if(s->type != SHOSTOBJ && !(s->type == SDYNIMPORT && s->reachable))
continue;
- putelfsyment(putelfstr(s->name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
+ if(s->type == SDYNIMPORT)
+ name = s->extname;
+ else
+ name = s->name;
+ putelfsyment(putelfstr(name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
s->elfsym = numelfsym++;
}
}
static void
-putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
+putplan9sym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
{
int i, l;
@@ -226,7 +247,7 @@ putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
case 'Z':
case 'm':
l = 4;
- if(HEADTYPE == Hplan9x64 && !debug['8']) {
+ if(HEADTYPE == Hplan9 && thechar == '6' && !debug['8']) {
lputb(addr>>32);
l = 8;
}
@@ -263,48 +284,7 @@ asmplan9sym(void)
genasmsym(putplan9sym);
}
-static Sym *symt;
-
-static void
-scput(int b)
-{
- uchar *p;
-
- symgrow(symt, symt->size+1);
- p = symt->p + symt->size;
- *p = b;
- symt->size++;
-}
-
-static void
-slputb(int32 v)
-{
- uchar *p;
-
- symgrow(symt, symt->size+4);
- p = symt->p + symt->size;
- *p++ = v>>24;
- *p++ = v>>16;
- *p++ = v>>8;
- *p = v;
- symt->size += 4;
-}
-
-static void
-slputl(int32 v)
-{
- uchar *p;
-
- symgrow(symt, symt->size+4);
- p = symt->p + symt->size;
- *p++ = v;
- *p++ = v>>8;
- *p++ = v>>16;
- *p = v>>24;
- symt->size += 4;
-}
-
-static void (*slput)(int32);
+static LSym *symt;
void
wputl(ushort w)
@@ -352,112 +332,10 @@ vputl(uint64 v)
lputl(v >> 32);
}
-// Emit symbol table entry.
-// The table format is described at the top of ../../pkg/runtime/symtab.c.
-void
-putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
-{
- int i, f, c;
- vlong v1;
- Reloc *rel;
-
- USED(size);
-
- // type byte
- if('A' <= t && t <= 'Z')
- c = t - 'A' + (ver ? 26 : 0);
- else if('a' <= t && t <= 'z')
- c = t - 'a' + 26;
- else {
- diag("invalid symbol table type %c", t);
- errorexit();
- return;
- }
-
- if(s != nil)
- c |= 0x40; // wide value
- if(typ != nil)
- c |= 0x80; // has go type
- scput(c);
-
- // value
- if(s != nil) {
- // full width
- rel = addrel(symt);
- rel->siz = PtrSize;
- rel->sym = s;
- rel->type = D_ADDR;
- rel->off = symt->size;
- if(PtrSize == 8)
- slput(0);
- slput(0);
- } else {
- // varint
- if(v < 0) {
- diag("negative value in symbol table: %s %lld", name, v);
- errorexit();
- }
- v1 = v;
- while(v1 >= 0x80) {
- scput(v1 | 0x80);
- v1 >>= 7;
- }
- scput(v1);
- }
-
- // go type if present
- if(typ != nil) {
- if(!typ->reachable)
- diag("unreachable type %s", typ->name);
- rel = addrel(symt);
- rel->siz = PtrSize;
- rel->sym = typ;
- rel->type = D_ADDR;
- rel->off = symt->size;
- if(PtrSize == 8)
- slput(0);
- slput(0);
- }
-
- // name
- if(t == 'f')
- name++;
-
- if(t == 'Z' || t == 'z') {
- scput(name[0]);
- for(i=1; name[i] != 0 || name[i+1] != 0; i += 2) {
- scput(name[i]);
- scput(name[i+1]);
- }
- scput(0);
- scput(0);
- } else {
- for(i=0; name[i]; i++)
- scput(name[i]);
- scput(0);
- }
-
- if(debug['n']) {
- if(t == 'z' || t == 'Z') {
- Bprint(&bso, "%c %.8llux ", t, v);
- for(i=1; name[i] != 0 || name[i+1] != 0; i+=2) {
- f = ((name[i]&0xff) << 8) | (name[i+1]&0xff);
- Bprint(&bso, "/%x", f);
- }
- Bprint(&bso, "\n");
- return;
- }
- if(ver)
- Bprint(&bso, "%c %.8llux %s<%d> %s\n", t, v, name, ver, typ ? typ->name : "");
- else
- Bprint(&bso, "%c %.8llux %s %s\n", t, v, name, typ ? typ->name : "");
- }
-}
-
void
symtab(void)
{
- Sym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
+ LSym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
dosymtype();
@@ -482,40 +360,40 @@ symtab(void)
xdefine("esymtab", SRODATA, 0);
// garbage collection symbols
- s = lookup("gcdata", 0);
+ s = linklookup(ctxt, "gcdata", 0);
s->type = SRODATA;
s->size = 0;
s->reachable = 1;
xdefine("egcdata", SRODATA, 0);
- s = lookup("gcbss", 0);
+ s = linklookup(ctxt, "gcbss", 0);
s->type = SRODATA;
s->size = 0;
s->reachable = 1;
xdefine("egcbss", SRODATA, 0);
// pseudo-symbols to mark locations of type, string, and go string data.
- s = lookup("type.*", 0);
+ s = linklookup(ctxt, "type.*", 0);
s->type = STYPE;
s->size = 0;
s->reachable = 1;
symtype = s;
- s = lookup("go.string.*", 0);
+ s = linklookup(ctxt, "go.string.*", 0);
s->type = SGOSTRING;
s->size = 0;
s->reachable = 1;
symgostring = s;
- s = lookup("go.func.*", 0);
+ s = linklookup(ctxt, "go.func.*", 0);
s->type = SGOFUNC;
s->size = 0;
s->reachable = 1;
symgofunc = s;
- symtypelink = lookup("typelink", 0);
+ symtypelink = linklookup(ctxt, "typelink", 0);
- symt = lookup("symtab", 0);
+ symt = linklookup(ctxt, "symtab", 0);
symt->type = SSYMTAB;
symt->size = 0;
symt->reachable = 1;
@@ -524,7 +402,7 @@ symtab(void)
// within a type they sort by size, so the .* symbols
// just defined above will be first.
// hide the specific symbols.
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(!s->reachable || s->special || s->type != SRODATA)
continue;
if(strncmp(s->name, "type.", 5) == 0) {
@@ -547,32 +425,12 @@ symtab(void)
s->hide = 1;
s->outer = symgofunc;
}
+ if(strncmp(s->name, "gcargs.", 7) == 0 || strncmp(s->name, "gclocals.", 9) == 0 || strncmp(s->name, "gclocals·", 10) == 0) {
+ s->type = SGOFUNC;
+ s->hide = 1;
+ s->outer = symgofunc;
+ s->align = 4;
+ liveness += (s->size+s->align-1)&~(s->align-1);
+ }
}
-
- if(debug['s'])
- return;
-
- switch(thechar) {
- default:
- diag("unknown architecture %c", thechar);
- errorexit();
- case '5':
- case '6':
- case '8':
- // little-endian symbol table
- slput = slputl;
- break;
- case 'v':
- // big-endian symbol table
- slput = slputb;
- break;
- }
- // new symbol table header.
- slput(0xfffffffd);
- scput(0);
- scput(0);
- scput(0);
- scput(PtrSize);
-
- genasmsym(putsymb);
}
diff --git a/src/cmd/ld/textflag.h b/src/cmd/ld/textflag.h
index 1d62db736..2a76e76c2 100644
--- a/src/cmd/ld/textflag.h
+++ b/src/cmd/ld/textflag.h
@@ -19,3 +19,5 @@
#define NOPTR 16
// This is a wrapper function and should not count as disabling 'recover'.
#define WRAPPER 32
+// This function uses its incoming context register.
+#define NEEDCTXT 64
diff --git a/src/cmd/nm/Makefile b/src/cmd/nm/Makefile
deleted file mode 100644
index 3f528d751..000000000
--- a/src/cmd/nm/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include ../../Make.dist
diff --git a/src/cmd/nm/debug_goobj.go b/src/cmd/nm/debug_goobj.go
new file mode 100644
index 000000000..9a067e2b9
--- /dev/null
+++ b/src/cmd/nm/debug_goobj.go
@@ -0,0 +1,670 @@
+// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
+// bundle -p main -x goobj_ debug/goobj
+
+/* read.go */
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package goobj implements reading of Go object files and archives.
+//
+// TODO(rsc): Decide where this package should live. (golang.org/issue/6932)
+// TODO(rsc): Decide the appropriate integer types for various fields.
+// TODO(rsc): Write tests. (File format still up in the air a little.)
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+)
+
+// A SymKind describes the kind of memory represented by a symbol.
+type goobj_SymKind int
+
+// This list is taken from include/link.h.
+
+// Defined SymKind values.
+// TODO(rsc): Give idiomatic Go names.
+// TODO(rsc): Reduce the number of symbol types in the object files.
+const (
+ _ goobj_SymKind = iota
+
+ // readonly, executable
+ goobj_STEXT
+ goobj_SELFRXSECT
+
+ // readonly, non-executable
+ goobj_STYPE
+ goobj_SSTRING
+ goobj_SGOSTRING
+ goobj_SGOFUNC
+ goobj_SRODATA
+ goobj_SFUNCTAB
+ goobj_STYPELINK
+ goobj_SSYMTAB // TODO: move to unmapped section
+ goobj_SPCLNTAB
+ goobj_SELFROSECT
+
+ // writable, non-executable
+ goobj_SMACHOPLT
+ goobj_SELFSECT
+ goobj_SMACHO // Mach-O __nl_symbol_ptr
+ goobj_SMACHOGOT
+ goobj_SNOPTRDATA
+ goobj_SINITARR
+ goobj_SDATA
+ goobj_SWINDOWS
+ goobj_SBSS
+ goobj_SNOPTRBSS
+ goobj_STLSBSS
+
+ // not mapped
+ goobj_SXREF
+ goobj_SMACHOSYMSTR
+ goobj_SMACHOSYMTAB
+ goobj_SMACHOINDIRECTPLT
+ goobj_SMACHOINDIRECTGOT
+ goobj_SFILE
+ goobj_SFILEPATH
+ goobj_SCONST
+ goobj_SDYNIMPORT
+ goobj_SHOSTOBJ
+)
+
+var goobj_symKindStrings = []string{
+ goobj_SBSS: "SBSS",
+ goobj_SCONST: "SCONST",
+ goobj_SDATA: "SDATA",
+ goobj_SDYNIMPORT: "SDYNIMPORT",
+ goobj_SELFROSECT: "SELFROSECT",
+ goobj_SELFRXSECT: "SELFRXSECT",
+ goobj_SELFSECT: "SELFSECT",
+ goobj_SFILE: "SFILE",
+ goobj_SFILEPATH: "SFILEPATH",
+ goobj_SFUNCTAB: "SFUNCTAB",
+ goobj_SGOFUNC: "SGOFUNC",
+ goobj_SGOSTRING: "SGOSTRING",
+ goobj_SHOSTOBJ: "SHOSTOBJ",
+ goobj_SINITARR: "SINITARR",
+ goobj_SMACHO: "SMACHO",
+ goobj_SMACHOGOT: "SMACHOGOT",
+ goobj_SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT",
+ goobj_SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT",
+ goobj_SMACHOPLT: "SMACHOPLT",
+ goobj_SMACHOSYMSTR: "SMACHOSYMSTR",
+ goobj_SMACHOSYMTAB: "SMACHOSYMTAB",
+ goobj_SNOPTRBSS: "SNOPTRBSS",
+ goobj_SNOPTRDATA: "SNOPTRDATA",
+ goobj_SPCLNTAB: "SPCLNTAB",
+ goobj_SRODATA: "SRODATA",
+ goobj_SSTRING: "SSTRING",
+ goobj_SSYMTAB: "SSYMTAB",
+ goobj_STEXT: "STEXT",
+ goobj_STLSBSS: "STLSBSS",
+ goobj_STYPE: "STYPE",
+ goobj_STYPELINK: "STYPELINK",
+ goobj_SWINDOWS: "SWINDOWS",
+ goobj_SXREF: "SXREF",
+}
+
+func (k goobj_SymKind) String() string {
+ if k < 0 || int(k) >= len(goobj_symKindStrings) {
+ return fmt.Sprintf("SymKind(%d)", k)
+ }
+ return goobj_symKindStrings[k]
+}
+
+// A Sym is a named symbol in an object file.
+type goobj_Sym struct {
+ goobj_SymID // symbol identifier (name and version)
+ Kind goobj_SymKind // kind of symbol
+ DupOK bool // are duplicate definitions okay?
+ Size int // size of corresponding data
+ Type goobj_SymID // symbol for Go type information
+ Data goobj_Data // memory image of symbol
+ Reloc []goobj_Reloc // relocations to apply to Data
+ Func *goobj_Func // additional data for functions
+}
+
+// A SymID - the combination of Name and Version - uniquely identifies
+// a symbol within a package.
+type goobj_SymID struct {
+ // Name is the name of a symbol.
+ Name string
+
+ // Version is zero for symbols with global visibility.
+ // Symbols with only file visibility (such as file-level static
+ // declarations in C) have a non-zero version distinguishing
+ // a symbol in one file from a symbol of the same name
+ // in another file
+ Version int
+}
+
+func (s goobj_SymID) String() string {
+ if s.Version == 0 {
+ return s.Name
+ }
+ return fmt.Sprintf("%s<%d>", s.Name, s.Version)
+}
+
+// A Data is a reference to data stored in an object file.
+// It records the offset and size of the data, so that a client can
+// read the data only if necessary.
+type goobj_Data struct {
+ Offset int64
+ Size int64
+}
+
+// A Reloc describes a relocation applied to a memory image to refer
+// to an address within a particular symbol.
+type goobj_Reloc struct {
+ // The bytes at [Offset, Offset+Size) within the memory image
+ // should be updated to refer to the address Add bytes after the start
+ // of the symbol Sym.
+ Offset int
+ Size int
+ Sym goobj_SymID
+ Add int
+
+ // The Type records the form of address expected in the bytes
+ // described by the previous fields: absolute, PC-relative, and so on.
+ // TODO(rsc): The interpretation of Type is not exposed by this package.
+ Type int
+}
+
+// A Var describes a variable in a function stack frame: a declared
+// local variable, an input argument, or an output result.
+type goobj_Var struct {
+ // The combination of Name, Kind, and Offset uniquely
+ // identifies a variable in a function stack frame.
+ // Using fewer of these - in particular, using only Name - does not.
+ Name string // Name of variable.
+ Kind int // TODO(rsc): Define meaning.
+ Offset int // Frame offset. TODO(rsc): Define meaning.
+
+ Type goobj_SymID // Go type for variable.
+}
+
+// Func contains additional per-symbol information specific to functions.
+type goobj_Func struct {
+ Args int // size in bytes of argument frame: inputs and outputs
+ Frame int // size in bytes of local variable frame
+ Leaf bool // function omits save of link register (ARM)
+ NoSplit bool // function omits stack split prologue
+ Var []goobj_Var // detail about local variables
+ PCSP goobj_Data // PC → SP offset map
+ PCFile goobj_Data // PC → file number map (index into File)
+ PCLine goobj_Data // PC → line number map
+ PCData []goobj_Data // PC → runtime support data map
+ FuncData []goobj_FuncData // non-PC-specific runtime support data
+ File []string // paths indexed by PCFile
+}
+
+// TODO: Add PCData []byte and PCDataIter (similar to liblink).
+
+// A FuncData is a single function-specific data value.
+type goobj_FuncData struct {
+ Sym goobj_SymID // symbol holding data
+ Offset int64 // offset into symbol for funcdata pointer
+}
+
+// A Package is a parsed Go object file or archive defining a Go package.
+type goobj_Package struct {
+ ImportPath string // import path denoting this package
+ Imports []string // packages imported by this package
+ Syms []*goobj_Sym // symbols defined by this package
+ MaxVersion int // maximum Version in any SymID in Syms
+}
+
+var (
+ goobj_archiveHeader = []byte("!<arch>\n")
+ goobj_archiveMagic = []byte("`\n")
+ goobj_goobjHeader = []byte("go objec") // truncated to size of archiveHeader
+
+ goobj_errCorruptArchive = errors.New("corrupt archive")
+ goobj_errTruncatedArchive = errors.New("truncated archive")
+ goobj_errNotArchive = errors.New("unrecognized archive format")
+
+ goobj_errCorruptObject = errors.New("corrupt object file")
+ goobj_errTruncatedObject = errors.New("truncated object file")
+ goobj_errNotObject = errors.New("unrecognized object file format")
+)
+
+// An objReader is an object file reader.
+type goobj_objReader struct {
+ p *goobj_Package
+ b *bufio.Reader
+ f io.ReadSeeker
+ err error
+ offset int64
+ limit int64
+ tmp [256]byte
+ pkg string
+ pkgprefix string
+}
+
+// importPathToPrefix returns the prefix that will be used in the
+// final symbol table for the given import path.
+// We escape '%', '"', all control characters and non-ASCII bytes,
+// and any '.' after the final slash.
+//
+// See ../../../cmd/ld/lib.c:/^pathtoprefix and
+// ../../../cmd/gc/subr.c:/^pathtoprefix.
+func goobj_importPathToPrefix(s string) string {
+ // find index of last slash, if any, or else -1.
+ // used for determining whether an index is after the last slash.
+ slash := strings.LastIndex(s, "/")
+
+ // check for chars that need escaping
+ n := 0
+ for r := 0; r < len(s); r++ {
+ if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
+ n++
+ }
+ }
+
+ // quick exit
+ if n == 0 {
+ return s
+ }
+
+ // escape
+ const hex = "0123456789abcdef"
+ p := make([]byte, 0, len(s)+2*n)
+ for r := 0; r < len(s); r++ {
+ if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
+ p = append(p, '%', hex[c>>4], hex[c&0xF])
+ } else {
+ p = append(p, c)
+ }
+ }
+
+ return string(p)
+}
+
+// init initializes r to read package p from f.
+func (r *goobj_objReader) init(f io.ReadSeeker, p *goobj_Package) {
+ r.f = f
+ r.p = p
+ r.offset, _ = f.Seek(0, 1)
+ r.limit, _ = f.Seek(0, 2)
+ f.Seek(r.offset, 0)
+ r.b = bufio.NewReader(f)
+ r.pkgprefix = goobj_importPathToPrefix(p.ImportPath) + "."
+}
+
+// error records that an error occurred.
+// It returns only the first error, so that an error
+// caused by an earlier error does not discard information
+// about the earlier error.
+func (r *goobj_objReader) error(err error) error {
+ if r.err == nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ r.err = err
+ }
+ // panic("corrupt") // useful for debugging
+ return r.err
+}
+
+// readByte reads and returns a byte from the input file.
+// On I/O error or EOF, it records the error but returns byte 0.
+// A sequence of 0 bytes will eventually terminate any
+// parsing state in the object file. In particular, it ends the
+// reading of a varint.
+func (r *goobj_objReader) readByte() byte {
+ if r.err != nil {
+ return 0
+ }
+ if r.offset >= r.limit {
+ r.error(io.ErrUnexpectedEOF)
+ return 0
+ }
+ b, err := r.b.ReadByte()
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ r.error(err)
+ b = 0
+ } else {
+ r.offset++
+ }
+ return b
+}
+
+// read reads exactly len(b) bytes from the input file.
+// If an error occurs, read returns the error but also
+// records it, so it is safe for callers to ignore the result
+// as long as delaying the report is not a problem.
+func (r *goobj_objReader) readFull(b []byte) error {
+ if r.err != nil {
+ return r.err
+ }
+ if r.offset+int64(len(b)) > r.limit {
+ return r.error(io.ErrUnexpectedEOF)
+ }
+ n, err := io.ReadFull(r.b, b)
+ r.offset += int64(n)
+ if err != nil {
+ return r.error(err)
+ }
+ return nil
+}
+
+// readInt reads a zigzag varint from the input file.
+func (r *goobj_objReader) readInt() int {
+ var u uint64
+
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ r.error(goobj_errCorruptObject)
+ return 0
+ }
+ c := r.readByte()
+ u |= uint64(c&0x7F) << shift
+ if c&0x80 == 0 {
+ break
+ }
+ }
+
+ v := int64(u>>1) ^ (int64(u) << 63 >> 63)
+ if int64(int(v)) != v {
+ r.error(goobj_errCorruptObject) // TODO
+ return 0
+ }
+ return int(v)
+}
+
+// readString reads a length-delimited string from the input file.
+func (r *goobj_objReader) readString() string {
+ n := r.readInt()
+ buf := make([]byte, n)
+ r.readFull(buf)
+ return string(buf)
+}
+
+// readSymID reads a SymID from the input file.
+func (r *goobj_objReader) readSymID() goobj_SymID {
+ name, vers := r.readString(), r.readInt()
+
+ // In a symbol name in an object file, "". denotes the
+ // prefix for the package in which the object file has been found.
+ // Expand it.
+ name = strings.Replace(name, `"".`, r.pkgprefix, -1)
+
+ // An individual object file only records version 0 (extern) or 1 (static).
+ // To make static symbols unique across all files being read, we
+ // replace version 1 with the version corresponding to the current
+ // file number. The number is incremented on each call to parseObject.
+ if vers != 0 {
+ vers = r.p.MaxVersion
+ }
+
+ return goobj_SymID{name, vers}
+}
+
+// readData reads a data reference from the input file.
+func (r *goobj_objReader) readData() goobj_Data {
+ n := r.readInt()
+ d := goobj_Data{Offset: r.offset, Size: int64(n)}
+ r.skip(int64(n))
+ return d
+}
+
+// skip skips n bytes in the input.
+func (r *goobj_objReader) skip(n int64) {
+ if n < 0 {
+ r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip"))
+ }
+ if n < int64(len(r.tmp)) {
+ // Since the data is so small, a just reading from the buffered
+ // reader is better than flushing the buffer and seeking.
+ r.readFull(r.tmp[:n])
+ } else if n <= int64(r.b.Buffered()) {
+ // Even though the data is not small, it has already been read.
+ // Advance the buffer instead of seeking.
+ for n > int64(len(r.tmp)) {
+ r.readFull(r.tmp[:])
+ n -= int64(len(r.tmp))
+ }
+ r.readFull(r.tmp[:n])
+ } else {
+ // Seek, giving up buffered data.
+ _, err := r.f.Seek(r.offset+n, 0)
+ if err != nil {
+ r.error(err)
+ }
+ r.offset += n
+ r.b.Reset(r.f)
+ }
+}
+
+// Parse parses an object file or archive from r,
+// assuming that its import path is pkgpath.
+func goobj_Parse(r io.ReadSeeker, pkgpath string) (*goobj_Package, error) {
+ if pkgpath == "" {
+ pkgpath = `""`
+ }
+ p := new(goobj_Package)
+ p.ImportPath = pkgpath
+
+ var rd goobj_objReader
+ rd.init(r, p)
+ err := rd.readFull(rd.tmp[:8])
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return nil, err
+ }
+
+ switch {
+ default:
+ return nil, goobj_errNotObject
+
+ case bytes.Equal(rd.tmp[:8], goobj_archiveHeader):
+ if err := rd.parseArchive(); err != nil {
+ return nil, err
+ }
+ case bytes.Equal(rd.tmp[:8], goobj_goobjHeader):
+ if err := rd.parseObject(goobj_goobjHeader); err != nil {
+ return nil, err
+ }
+ }
+
+ return p, nil
+}
+
+// trimSpace removes trailing spaces from b and returns the corresponding string.
+// This effectively parses the form used in archive headers.
+func goobj_trimSpace(b []byte) string {
+ return string(bytes.TrimRight(b, " "))
+}
+
+// parseArchive parses a Unix archive of Go object files.
+// TODO(rsc): Need to skip non-Go object files.
+// TODO(rsc): Maybe record table of contents in r.p so that
+// linker can avoid having code to parse archives too.
+func (r *goobj_objReader) parseArchive() error {
+ for r.offset < r.limit {
+ if err := r.readFull(r.tmp[:60]); err != nil {
+ return err
+ }
+ data := r.tmp[:60]
+
+ // Each file is preceded by this text header (slice indices in first column):
+ // 0:16 name
+ // 16:28 date
+ // 28:34 uid
+ // 34:40 gid
+ // 40:48 mode
+ // 48:58 size
+ // 58:60 magic - `\n
+ // We only care about name, size, and magic.
+ // The fields are space-padded on the right.
+ // The size is in decimal.
+ // The file data - size bytes - follows the header.
+ // Headers are 2-byte aligned, so if size is odd, an extra padding
+ // byte sits between the file data and the next header.
+ // The file data that follows is padded to an even number of bytes:
+ // if size is odd, an extra padding byte is inserted betw the next header.
+ if len(data) < 60 {
+ return goobj_errTruncatedArchive
+ }
+ if !bytes.Equal(data[58:60], goobj_archiveMagic) {
+ return goobj_errCorruptArchive
+ }
+ name := goobj_trimSpace(data[0:16])
+ size, err := strconv.ParseInt(goobj_trimSpace(data[48:58]), 10, 64)
+ if err != nil {
+ return goobj_errCorruptArchive
+ }
+ data = data[60:]
+ fsize := size + size&1
+ if fsize < 0 || fsize < size {
+ return goobj_errCorruptArchive
+ }
+ switch name {
+ case "__.SYMDEF", "__.GOSYMDEF", "__.PKGDEF":
+ r.skip(size)
+ default:
+ oldLimit := r.limit
+ r.limit = r.offset + size
+ if err := r.parseObject(nil); err != nil {
+ return fmt.Errorf("parsing archive member %q: %v", name, err)
+ }
+ r.skip(r.limit - r.offset)
+ r.limit = oldLimit
+ }
+ if size&1 != 0 {
+ r.skip(1)
+ }
+ }
+ return nil
+}
+
+// parseObject parses a single Go object file.
+// The prefix is the bytes already read from the file,
+// typically in order to detect that this is an object file.
+// The object file consists of a textual header ending in "\n!\n"
+// and then the part we want to parse begins.
+// The format of that part is defined in a comment at the top
+// of src/liblink/objfile.c.
+func (r *goobj_objReader) parseObject(prefix []byte) error {
+ // TODO(rsc): Maybe use prefix and the initial input to
+ // record the header line from the file, which would
+ // give the architecture and other version information.
+
+ r.p.MaxVersion++
+ var c1, c2, c3 byte
+ for {
+ c1, c2, c3 = c2, c3, r.readByte()
+ if c3 == 0 { // NUL or EOF, either is bad
+ return goobj_errCorruptObject
+ }
+ if c1 == '\n' && c2 == '!' && c3 == '\n' {
+ break
+ }
+ }
+
+ r.readFull(r.tmp[:8])
+ if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go13ld")) {
+ return r.error(goobj_errCorruptObject)
+ }
+
+ b := r.readByte()
+ if b != 1 {
+ return r.error(goobj_errCorruptObject)
+ }
+
+ // Direct package dependencies.
+ for {
+ s := r.readString()
+ if s == "" {
+ break
+ }
+ r.p.Imports = append(r.p.Imports, s)
+ }
+
+ // Symbols.
+ for {
+ if b := r.readByte(); b != 0xfe {
+ if b != 0xff {
+ return r.error(goobj_errCorruptObject)
+ }
+ break
+ }
+
+ typ := r.readInt()
+ s := &goobj_Sym{goobj_SymID: r.readSymID()}
+ r.p.Syms = append(r.p.Syms, s)
+ s.Kind = goobj_SymKind(typ)
+ s.DupOK = r.readInt() != 0
+ s.Size = r.readInt()
+ s.Type = r.readSymID()
+ s.Data = r.readData()
+ s.Reloc = make([]goobj_Reloc, r.readInt())
+ for i := range s.Reloc {
+ rel := &s.Reloc[i]
+ rel.Offset = r.readInt()
+ rel.Size = r.readInt()
+ rel.Type = r.readInt()
+ rel.Add = r.readInt()
+ r.readInt() // Xadd - ignored
+ rel.Sym = r.readSymID()
+ r.readSymID() // Xsym - ignored
+ }
+
+ if s.Kind == goobj_STEXT {
+ f := new(goobj_Func)
+ s.Func = f
+ f.Args = r.readInt()
+ f.Frame = r.readInt()
+ f.Leaf = r.readInt() != 0
+ f.NoSplit = r.readInt() != 0
+ f.Var = make([]goobj_Var, r.readInt())
+ for i := range f.Var {
+ v := &f.Var[i]
+ v.Name = r.readSymID().Name
+ v.Offset = r.readInt()
+ v.Kind = r.readInt()
+ v.Type = r.readSymID()
+ }
+
+ f.PCSP = r.readData()
+ f.PCFile = r.readData()
+ f.PCLine = r.readData()
+ f.PCData = make([]goobj_Data, r.readInt())
+ for i := range f.PCData {
+ f.PCData[i] = r.readData()
+ }
+ f.FuncData = make([]goobj_FuncData, r.readInt())
+ for i := range f.FuncData {
+ f.FuncData[i].Sym = r.readSymID()
+ }
+ for i := range f.FuncData {
+ f.FuncData[i].Offset = int64(r.readInt()) // TODO
+ }
+ f.File = make([]string, r.readInt())
+ for i := range f.File {
+ f.File[i] = r.readSymID().Name
+ }
+ }
+ }
+
+ r.readFull(r.tmp[:7])
+ if !bytes.Equal(r.tmp[:7], []byte("\xffgo13ld")) {
+ return r.error(goobj_errCorruptObject)
+ }
+
+ return nil
+}
diff --git a/src/cmd/nm/doc.go b/src/cmd/nm/doc.go
index 8e88e2e63..b62da47c0 100644
--- a/src/cmd/nm/doc.go
+++ b/src/cmd/nm/doc.go
@@ -1,23 +1,41 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build ignore
-
-/*
-
-Nm is a version of the Plan 9 nm command. The original is documented at
-
- http://plan9.bell-labs.com/magic/man2html/1/nm
-
-It prints the name list (symbol table) for programs compiled by gc as well as the
-Plan 9 C compiler.
-
-This implementation adds the flag -S, which prints each symbol's size
-in decimal after its address.
-
-Usage:
- go tool nm [-aghnsSTu] file
-
-*/
+// Nm lists the symbols defined or used by an object file, archive, or executable.
+//
+// Usage:
+// go tool nm [options] file...
+//
+// The default output prints one line per symbol, with three space-separated
+// fields giving the address (in hexadecimal), type (a character), and name of
+// the symbol. The types are:
+//
+// T text (code) segment symbol
+// t static text segment symbol
+// R read-only data segment symbol
+// r static read-only data segment symbol
+// D data segment symbol
+// d static data segment symbol
+// B bss segment symbol
+// b static bss segment symbol
+// C constant address
+// U referenced but undefined symbol
+//
+// Following established convention, the address is omitted for undefined
+// symbols (type U).
+//
+// The options control the printed output:
+//
+// -n
+// an alias for -sort address (numeric),
+// for compatibility with other nm commands
+// -size
+// print symbol size in decimal between address and type
+// -sort {address,name,none,size}
+// sort output in the given order (default name)
+// size orders from largest to smallest
+// -type
+// print symbol type after name
+//
package main
diff --git a/src/cmd/nm/elf.go b/src/cmd/nm/elf.go
new file mode 100644
index 000000000..5aaa194dd
--- /dev/null
+++ b/src/cmd/nm/elf.go
@@ -0,0 +1,57 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of ELF executables (Linux, FreeBSD, and so on).
+
+package main
+
+import (
+ "debug/elf"
+ "os"
+)
+
+func elfSymbols(f *os.File) []Sym {
+ p, err := elf.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ elfSyms, err := p.Symbols()
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ var syms []Sym
+ for _, s := range elfSyms {
+ sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
+ switch s.Section {
+ case elf.SHN_UNDEF:
+ sym.Code = 'U'
+ case elf.SHN_COMMON:
+ sym.Code = 'B'
+ default:
+ i := int(s.Section)
+ if i < 0 || i >= len(p.Sections) {
+ break
+ }
+ sect := p.Sections[i]
+ switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
+ case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
+ sym.Code = 'T'
+ case elf.SHF_ALLOC:
+ sym.Code = 'R'
+ case elf.SHF_ALLOC | elf.SHF_WRITE:
+ sym.Code = 'D'
+ }
+ }
+ if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
+ sym.Code += 'a' - 'A'
+ }
+ syms = append(syms, sym)
+ }
+
+ return syms
+}
diff --git a/src/cmd/nm/goobj.go b/src/cmd/nm/goobj.go
new file mode 100644
index 000000000..5e0817d95
--- /dev/null
+++ b/src/cmd/nm/goobj.go
@@ -0,0 +1,67 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Go intermediate object files and archives.
+
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func goobjName(id goobj_SymID) string {
+ if id.Version == 0 {
+ return id.Name
+ }
+ return fmt.Sprintf("%s<%d>", id.Name, id.Version)
+}
+
+func goobjSymbols(f *os.File) []Sym {
+ pkg, err := goobj_Parse(f, `""`)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ seen := make(map[goobj_SymID]bool)
+
+ var syms []Sym
+ for _, s := range pkg.Syms {
+ seen[s.goobj_SymID] = true
+ sym := Sym{Addr: uint64(s.Data.Offset), Name: goobjName(s.goobj_SymID), Size: int64(s.Size), Type: s.Type.Name, Code: '?'}
+ switch s.Kind {
+ case goobj_STEXT, goobj_SELFRXSECT:
+ sym.Code = 'T'
+ case goobj_STYPE, goobj_SSTRING, goobj_SGOSTRING, goobj_SGOFUNC, goobj_SRODATA, goobj_SFUNCTAB, goobj_STYPELINK, goobj_SSYMTAB, goobj_SPCLNTAB, goobj_SELFROSECT:
+ sym.Code = 'R'
+ case goobj_SMACHOPLT, goobj_SELFSECT, goobj_SMACHO, goobj_SMACHOGOT, goobj_SNOPTRDATA, goobj_SINITARR, goobj_SDATA, goobj_SWINDOWS:
+ sym.Code = 'D'
+ case goobj_SBSS, goobj_SNOPTRBSS, goobj_STLSBSS:
+ sym.Code = 'B'
+ case goobj_SXREF, goobj_SMACHOSYMSTR, goobj_SMACHOSYMTAB, goobj_SMACHOINDIRECTPLT, goobj_SMACHOINDIRECTGOT, goobj_SFILE, goobj_SFILEPATH, goobj_SCONST, goobj_SDYNIMPORT, goobj_SHOSTOBJ:
+ sym.Code = 'X' // should not see
+ }
+ if s.Version != 0 {
+ sym.Code += 'a' - 'A'
+ }
+ syms = append(syms, sym)
+ }
+
+ for _, s := range pkg.Syms {
+ for _, r := range s.Reloc {
+ if !seen[r.Sym] {
+ seen[r.Sym] = true
+ sym := Sym{Name: goobjName(r.Sym), Code: 'U'}
+ if s.Version != 0 {
+ // should not happen but handle anyway
+ sym.Code = 'u'
+ }
+ syms = append(syms, sym)
+ }
+ }
+ }
+
+ return syms
+}
diff --git a/src/cmd/nm/macho.go b/src/cmd/nm/macho.go
new file mode 100644
index 000000000..c60bde55b
--- /dev/null
+++ b/src/cmd/nm/macho.go
@@ -0,0 +1,69 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Mach-O executables (OS X).
+
+package main
+
+import (
+ "debug/macho"
+ "os"
+ "sort"
+)
+
+func machoSymbols(f *os.File) []Sym {
+ p, err := macho.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ if p.Symtab == nil {
+ errorf("%s: no symbol table", f.Name())
+ return nil
+ }
+
+ // Build sorted list of addresses of all symbols.
+ // We infer the size of a symbol by looking at where the next symbol begins.
+ var addrs []uint64
+ for _, s := range p.Symtab.Syms {
+ addrs = append(addrs, s.Value)
+ }
+ sort.Sort(uint64s(addrs))
+
+ var syms []Sym
+ for _, s := range p.Symtab.Syms {
+ sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
+ i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
+ if i < len(addrs) {
+ sym.Size = int64(addrs[i] - s.Value)
+ }
+ if s.Sect == 0 {
+ sym.Code = 'U'
+ } else if int(s.Sect) <= len(p.Sections) {
+ sect := p.Sections[s.Sect-1]
+ switch sect.Seg {
+ case "__TEXT":
+ sym.Code = 'R'
+ case "__DATA":
+ sym.Code = 'D'
+ }
+ switch sect.Seg + " " + sect.Name {
+ case "__TEXT __text":
+ sym.Code = 'T'
+ case "__DATA __bss", "__DATA __noptrbss":
+ sym.Code = 'B'
+ }
+ }
+ syms = append(syms, sym)
+ }
+
+ return syms
+}
+
+type uint64s []uint64
+
+func (x uint64s) Len() int { return len(x) }
+func (x uint64s) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
diff --git a/src/cmd/nm/nm.c b/src/cmd/nm/nm.c
deleted file mode 100644
index 820942426..000000000
--- a/src/cmd/nm/nm.c
+++ /dev/null
@@ -1,401 +0,0 @@
-// Inferno utils/nm/nm.c
-// http://code.google.com/p/inferno-os/source/browse/utils/nm/nm.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.
-
-/*
- * nm.c -- drive nm
- */
-#include <u.h>
-#include <libc.h>
-#include <ar.h>
-#include <bio.h>
-#include <mach.h>
-
-enum{
- CHUNK = 256 /* must be power of 2 */
-};
-
-char *errs; /* exit status */
-char *filename; /* current file */
-char symname[]="__.GOSYMDEF"; /* table of contents file name */
-int multifile; /* processing multiple files */
-int aflag;
-int gflag;
-int hflag;
-int nflag;
-int sflag;
-int Sflag;
-int uflag;
-int Tflag;
-int tflag;
-
-Sym **fnames; /* file path translation table */
-Sym **symptr;
-int nsym;
-Biobuf bout;
-
-int cmp(void*, void*);
-void error(char*, ...);
-void execsyms(int);
-void psym(Sym*, void*);
-void printsyms(Sym**, long);
-void doar(Biobuf*);
-void dofile(Biobuf*);
-void zenter(Sym*);
-
-void
-usage(void)
-{
- fprint(2, "usage: nm [-aghnsSTu] file ...\n");
- exits("usage");
-}
-
-void
-main(int argc, char *argv[])
-{
- int i;
- Biobuf *bin;
-
- Binit(&bout, 1, OWRITE);
- argv0 = argv[0];
- ARGBEGIN {
- default: usage();
- case 'a': aflag = 1; break;
- case 'g': gflag = 1; break;
- case 'h': hflag = 1; break;
- case 'n': nflag = 1; break;
- case 's': sflag = 1; break;
- case 'S': nflag = Sflag = 1; break;
- case 'u': uflag = 1; break;
- case 't': tflag = 1; break;
- case 'T': Tflag = 1; break;
- } ARGEND
- if (argc == 0)
- usage();
- if (argc > 1)
- multifile++;
- for(i=0; i<argc; i++){
- filename = argv[i];
- bin = Bopen(filename, OREAD);
- if(bin == 0){
- error("cannot open %s", filename);
- continue;
- }
- if (isar(bin))
- doar(bin);
- else{
- Bseek(bin, 0, 0);
- dofile(bin);
- }
- Bterm(bin);
- }
- exits(errs);
-}
-
-/*
- * read an archive file,
- * processing the symbols for each intermediate file in it.
- */
-void
-doar(Biobuf *bp)
-{
- int offset, size, obj;
- char name[SARNAME];
-
- multifile = 1;
- for (offset = Boffset(bp);;offset += size) {
- size = nextar(bp, offset, name);
- if (size < 0) {
- error("phase error on ar header %d", offset);
- return;
- }
- if (size == 0)
- return;
- if (strcmp(name, symname) == 0)
- continue;
- obj = objtype(bp, 0);
- if (obj < 0) {
- // perhaps foreign object
- if(strlen(name) > 2 && strcmp(name+strlen(name)-2, ".o") == 0)
- return;
- error("inconsistent file %s in %s",
- name, filename);
- return;
- }
- if (!readar(bp, obj, offset+size, 1)) {
- error("invalid symbol reference in file %s",
- name);
- return;
- }
- filename = name;
- nsym=0;
- objtraverse(psym, 0);
- printsyms(symptr, nsym);
- }
-}
-
-/*
- * process symbols in a file
- */
-void
-dofile(Biobuf *bp)
-{
- int obj;
-
- obj = objtype(bp, 0);
- if (obj < 0)
- execsyms(Bfildes(bp));
- else
- if (readobj(bp, obj)) {
- nsym = 0;
- objtraverse(psym, 0);
- printsyms(symptr, nsym);
- }
-}
-
-/*
- * comparison routine for sorting the symbol table
- * this screws up on 'z' records when aflag == 1
- */
-int
-cmp(void *vs, void *vt)
-{
- Sym **s, **t;
-
- s = vs;
- t = vt;
- if(nflag) // sort on address (numeric) order
- if((*s)->value < (*t)->value)
- return -1;
- else
- return (*s)->value > (*t)->value;
- if(sflag) // sort on file order (sequence)
- return (*s)->sequence - (*t)->sequence;
- return strcmp((*s)->name, (*t)->name);
-}
-/*
- * enter a symbol in the table of filename elements
- */
-void
-zenter(Sym *s)
-{
- static int maxf = 0;
-
- if (s->value > maxf) {
- maxf = (s->value+CHUNK-1) &~ (CHUNK-1);
- fnames = realloc(fnames, (maxf+1)*sizeof(*fnames));
- if(fnames == 0) {
- error("out of memory", argv0);
- exits("memory");
- }
- }
- fnames[s->value] = s;
-}
-
-/*
- * get the symbol table from an executable file, if it has one
- */
-void
-execsyms(int fd)
-{
- Fhdr f;
- Sym *s;
- int32 n;
-
- seek(fd, 0, 0);
- if (crackhdr(fd, &f) == 0) {
- error("Can't read header for %s", filename);
- return;
- }
- if (syminit(fd, &f) < 0)
- return;
- s = symbase(&n);
- nsym = 0;
- while(n--)
- psym(s++, 0);
-
- printsyms(symptr, nsym);
-}
-
-void
-psym(Sym *s, void* p)
-{
- USED(p);
- switch(s->type) {
- case 'T':
- case 'L':
- case 'D':
- case 'B':
- if (uflag)
- return;
- if (!aflag && ((s->name[0] == '.' || s->name[0] == '$')))
- return;
- break;
- case 'b':
- case 'd':
- case 'l':
- case 't':
- if (uflag || gflag)
- return;
- if (!aflag && ((s->name[0] == '.' || s->name[0] == '$')))
- return;
- break;
- case 'U':
- if (gflag)
- return;
- break;
- case 'Z':
- if (!aflag)
- return;
- break;
- case 'm':
- if(!aflag || uflag || gflag)
- return;
- break;
- case 'f': /* we only see a 'z' when the following is true*/
- if(!aflag || uflag || gflag)
- return;
- zenter(s);
- break;
- case 'a':
- case 'p':
- case 'z':
- default:
- if(!aflag || uflag || gflag)
- return;
- break;
- }
- symptr = realloc(symptr, (nsym+1)*sizeof(Sym*));
- if (symptr == 0) {
- error("out of memory");
- exits("memory");
- }
- symptr[nsym++] = s;
-}
-
-const char *skipnames[] = {
- "bss",
- "data",
- "ebss",
- "edata",
- "egcbss",
- "egcdata",
- "enoptrbss",
- "enoptrdata",
- "epclntab",
- "erodata",
- "esymtab",
- "etext",
- "etypelink",
- "noptrbss",
- "noptrdata",
- "rodata",
- "text",
-};
-
-int
-skipsize(char *name)
-{
- int i;
-
- for(i=0; i<nelem(skipnames); i++)
- if(strcmp(skipnames[i], name) == 0)
- return 1;
- return 0;
-}
-
-void
-printsyms(Sym **symptr, long nsym)
-{
- int i, j, wid;
- Sym *s;
- char *cp;
- char path[512];
-
- qsort(symptr, nsym, sizeof(*symptr), (void*)cmp);
-
- wid = 0;
- for (i=0; i<nsym; i++) {
- s = symptr[i];
- if (s->value && wid == 0)
- wid = 8;
- else if (s->value >= 0x100000000LL && wid == 8)
- wid = 16;
- }
- for (i=0; i<nsym; i++) {
- s = symptr[i];
- if (multifile && !hflag)
- Bprint(&bout, "%s:", filename);
- if (s->type == 'z') {
- fileelem(fnames, (uchar *) s->name, path, 512);
- cp = path;
- } else
- cp = s->name;
- if (Tflag)
- Bprint(&bout, "%8ux ", s->sig);
- if (s->value || s->type == 'a' || s->type == 'p')
- Bprint(&bout, "%*llux ", wid, s->value);
- else
- Bprint(&bout, "%*s ", wid, "");
- if(Sflag && !skipsize(cp)) {
- vlong siz;
-
- siz = 0;
- for(j=i+1; j<nsym; j++) {
- if(!skipsize(symptr[j]->name) && symptr[j]->type != 'a' && symptr[j]->type != 'p') {
- siz = symptr[j]->value - s->value;
- break;
- }
- }
- if(siz > 0)
- Bprint(&bout, "%*llud ", wid, siz);
- }
- Bprint(&bout, "%c %s", s->type, cp);
- if(tflag && s->gotype)
- Bprint(&bout, " %*llux", wid, s->gotype);
- Bprint(&bout, "\n");
- }
-}
-
-void
-error(char *fmt, ...)
-{
- Fmt f;
- char buf[128];
- va_list arg;
-
- fmtfdinit(&f, 2, buf, sizeof buf);
- fmtprint(&f, "%s: ", argv0);
- va_start(arg, fmt);
- fmtvprint(&f, fmt, arg);
- va_end(arg);
- fmtprint(&f, "\n");
- fmtfdflush(&f);
- errs = "errors";
-}
diff --git a/src/cmd/nm/nm.go b/src/cmd/nm/nm.go
new file mode 100644
index 000000000..a4036184e
--- /dev/null
+++ b/src/cmd/nm/nm.go
@@ -0,0 +1,184 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "sort"
+)
+
+func usage() {
+ fmt.Fprintf(os.Stderr, "usage: go tool nm [-n] [-size] [-sort order] [-type] file...\n")
+ os.Exit(2)
+}
+
+var (
+ sortOrder = flag.String("sort", "name", "")
+ printSize = flag.Bool("size", false, "")
+ printType = flag.Bool("type", false, "")
+
+ filePrefix = false
+)
+
+func init() {
+ flag.Var(nflag(0), "n", "") // alias for -sort address
+}
+
+type nflag int
+
+func (nflag) IsBoolFlag() bool {
+ return true
+}
+
+func (nflag) Set(value string) error {
+ if value == "true" {
+ *sortOrder = "address"
+ }
+ return nil
+}
+
+func (nflag) String() string {
+ if *sortOrder == "address" {
+ return "true"
+ }
+ return "false"
+}
+
+func main() {
+ log.SetFlags(0)
+ flag.Usage = usage
+ flag.Parse()
+
+ switch *sortOrder {
+ case "address", "name", "none", "size":
+ // ok
+ default:
+ fmt.Fprintf(os.Stderr, "nm: unknown sort order %q\n", *sortOrder)
+ os.Exit(2)
+ }
+
+ args := flag.Args()
+ filePrefix = len(args) > 1
+ if len(args) == 0 {
+ flag.Usage()
+ }
+
+ for _, file := range args {
+ nm(file)
+ }
+
+ os.Exit(exitCode)
+}
+
+var exitCode = 0
+
+func errorf(format string, args ...interface{}) {
+ log.Printf(format, args...)
+ exitCode = 1
+}
+
+type Sym struct {
+ Addr uint64
+ Size int64
+ Code rune
+ Name string
+ Type string
+}
+
+var parsers = []struct {
+ prefix []byte
+ parse func(*os.File) []Sym
+}{
+ {[]byte("!<arch>\n"), goobjSymbols},
+ {[]byte("go object "), goobjSymbols},
+ {[]byte("\x7FELF"), elfSymbols},
+ {[]byte("\xFE\xED\xFA\xCE"), machoSymbols},
+ {[]byte("\xFE\xED\xFA\xCF"), machoSymbols},
+ {[]byte("\xCE\xFA\xED\xFE"), machoSymbols},
+ {[]byte("\xCF\xFA\xED\xFE"), machoSymbols},
+ {[]byte("MZ"), peSymbols},
+ {[]byte("\x00\x00\x01\xEB"), plan9Symbols}, // 386
+ {[]byte("\x00\x00\x04\x07"), plan9Symbols}, // mips
+ {[]byte("\x00\x00\x06\x47"), plan9Symbols}, // arm
+ {[]byte("\x00\x00\x8A\x97"), plan9Symbols}, // amd64
+}
+
+func nm(file string) {
+ f, err := os.Open(file)
+ if err != nil {
+ errorf("%v", err)
+ return
+ }
+ defer f.Close()
+
+ buf := make([]byte, 16)
+ io.ReadFull(f, buf)
+ f.Seek(0, 0)
+
+ var syms []Sym
+ for _, p := range parsers {
+ if bytes.HasPrefix(buf, p.prefix) {
+ syms = p.parse(f)
+ goto HaveSyms
+ }
+ }
+ errorf("%v: unknown file format", file)
+ return
+
+HaveSyms:
+ switch *sortOrder {
+ case "address":
+ sort.Sort(byAddr(syms))
+ case "name":
+ sort.Sort(byName(syms))
+ case "size":
+ sort.Sort(bySize(syms))
+ }
+
+ w := bufio.NewWriter(os.Stdout)
+ for _, sym := range syms {
+ if filePrefix {
+ fmt.Fprintf(w, "%s:\t", file)
+ }
+ if sym.Code == 'U' {
+ fmt.Fprintf(w, "%8s", "")
+ } else {
+ fmt.Fprintf(w, "%8x", sym.Addr)
+ }
+ if *printSize {
+ fmt.Fprintf(w, " %10d", sym.Size)
+ }
+ fmt.Fprintf(w, " %c %s", sym.Code, sym.Name)
+ if *printType && sym.Type != "" {
+ fmt.Fprintf(w, " %s", sym.Type)
+ }
+ fmt.Fprintf(w, "\n")
+ }
+ w.Flush()
+}
+
+type byAddr []Sym
+
+func (x byAddr) Len() int { return len(x) }
+func (x byAddr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
+
+type byName []Sym
+
+func (x byName) Len() int { return len(x) }
+func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byName) Less(i, j int) bool { return x[i].Name < x[j].Name }
+
+type bySize []Sym
+
+func (x bySize) Len() int { return len(x) }
+func (x bySize) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x bySize) Less(i, j int) bool { return x[i].Size > x[j].Size }
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
new file mode 100644
index 000000000..f4e47a42d
--- /dev/null
+++ b/src/cmd/nm/nm_test.go
@@ -0,0 +1,99 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+)
+
+var testData uint32
+
+func checkSymbols(t *testing.T, nmoutput []byte) {
+ var checkSymbolsFound, testDataFound bool
+ scanner := bufio.NewScanner(bytes.NewBuffer(nmoutput))
+ for scanner.Scan() {
+ f := strings.Fields(scanner.Text())
+ if len(f) < 3 {
+ continue
+ }
+ switch f[2] {
+ case "cmd/nm.checkSymbols":
+ checkSymbolsFound = true
+ addr := "0x" + f[0]
+ if addr != fmt.Sprintf("%p", checkSymbols) {
+ t.Errorf("nm shows wrong address %v for checkSymbols (%p)", addr, checkSymbols)
+ }
+ case "cmd/nm.testData":
+ testDataFound = true
+ addr := "0x" + f[0]
+ if addr != fmt.Sprintf("%p", &testData) {
+ t.Errorf("nm shows wrong address %v for testData (%p)", addr, &testData)
+ }
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ t.Errorf("error while reading symbols: %v", err)
+ return
+ }
+ if !checkSymbolsFound {
+ t.Error("nm shows no checkSymbols symbol")
+ }
+ if !testDataFound {
+ t.Error("nm shows no testData symbol")
+ }
+}
+
+func TestNM(t *testing.T) {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ tmpDir, err := ioutil.TempDir("", "TestNM")
+ if err != nil {
+ t.Fatal("TempDir failed: ", err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ testnmpath := filepath.Join(tmpDir, "testnm.exe")
+ out, err := exec.Command("go", "build", "-o", testnmpath, "cmd/nm").CombinedOutput()
+ if err != nil {
+ t.Fatalf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out))
+ }
+
+ testfiles := []string{
+ "elf/testdata/gcc-386-freebsd-exec",
+ "elf/testdata/gcc-amd64-linux-exec",
+ "macho/testdata/gcc-386-darwin-exec",
+ "macho/testdata/gcc-amd64-darwin-exec",
+ "pe/testdata/gcc-amd64-mingw-exec",
+ "pe/testdata/gcc-386-mingw-exec",
+ "plan9obj/testdata/amd64-plan9-exec",
+ "plan9obj/testdata/386-plan9-exec",
+ }
+ for _, f := range testfiles {
+ exepath := filepath.Join(runtime.GOROOT(), "src", "pkg", "debug", f)
+ cmd := exec.Command(testnmpath, exepath)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm %v: %v\n%s", exepath, err, string(out))
+ }
+ }
+
+ cmd := exec.Command(testnmpath, os.Args[0])
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ checkSymbols(t, out)
+}
diff --git a/src/cmd/nm/pe.go b/src/cmd/nm/pe.go
new file mode 100644
index 000000000..52d05e51d
--- /dev/null
+++ b/src/cmd/nm/pe.go
@@ -0,0 +1,98 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of PE executables (Microsoft Windows).
+
+package main
+
+import (
+ "debug/pe"
+ "os"
+ "sort"
+)
+
+func peSymbols(f *os.File) []Sym {
+ p, err := pe.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ // Build sorted list of addresses of all symbols.
+ // We infer the size of a symbol by looking at where the next symbol begins.
+ var addrs []uint64
+
+ var imageBase uint64
+ switch oh := p.OptionalHeader.(type) {
+ case *pe.OptionalHeader32:
+ imageBase = uint64(oh.ImageBase)
+ case *pe.OptionalHeader64:
+ imageBase = oh.ImageBase
+ default:
+ errorf("parsing %s: file format not recognized", f.Name())
+ return nil
+ }
+
+ var syms []Sym
+ for _, s := range p.Symbols {
+ const (
+ N_UNDEF = 0 // An undefined (extern) symbol
+ N_ABS = -1 // An absolute symbol (e_value is a constant, not an address)
+ N_DEBUG = -2 // A debugging symbol
+ )
+ sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
+ switch s.SectionNumber {
+ case N_UNDEF:
+ sym.Code = 'U'
+ case N_ABS:
+ sym.Code = 'C'
+ case N_DEBUG:
+ sym.Code = '?'
+ default:
+ if s.SectionNumber < 0 {
+ errorf("parsing %s: invalid section number %d", f.Name(), s.SectionNumber)
+ return nil
+ }
+ if len(p.Sections) < int(s.SectionNumber) {
+ errorf("parsing %s: section number %d is large then max %d", f.Name(), s.SectionNumber, len(p.Sections))
+ return nil
+ }
+ sect := p.Sections[s.SectionNumber-1]
+ const (
+ text = 0x20
+ data = 0x40
+ bss = 0x80
+ permX = 0x20000000
+ permR = 0x40000000
+ permW = 0x80000000
+ )
+ ch := sect.Characteristics
+ switch {
+ case ch&text != 0:
+ sym.Code = 'T'
+ case ch&data != 0:
+ if ch&permW == 0 {
+ sym.Code = 'R'
+ } else {
+ sym.Code = 'D'
+ }
+ case ch&bss != 0:
+ sym.Code = 'B'
+ }
+ sym.Addr += imageBase + uint64(sect.VirtualAddress)
+ }
+ syms = append(syms, sym)
+ addrs = append(addrs, sym.Addr)
+ }
+
+ sort.Sort(uint64s(addrs))
+ for i := range syms {
+ j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
+ if j < len(addrs) {
+ syms[i].Size = int64(addrs[j] - syms[i].Addr)
+ }
+ }
+
+ return syms
+}
diff --git a/src/cmd/nm/plan9obj.go b/src/cmd/nm/plan9obj.go
new file mode 100644
index 000000000..006c66ebf
--- /dev/null
+++ b/src/cmd/nm/plan9obj.go
@@ -0,0 +1,48 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Plan 9 a.out executables.
+
+package main
+
+import (
+ "debug/plan9obj"
+ "os"
+ "sort"
+)
+
+func plan9Symbols(f *os.File) []Sym {
+ p, err := plan9obj.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ plan9Syms, err := p.Symbols()
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return nil
+ }
+
+ // Build sorted list of addresses of all symbols.
+ // We infer the size of a symbol by looking at where the next symbol begins.
+ var addrs []uint64
+ for _, s := range plan9Syms {
+ addrs = append(addrs, s.Value)
+ }
+ sort.Sort(uint64s(addrs))
+
+ var syms []Sym
+
+ for _, s := range plan9Syms {
+ sym := Sym{Addr: s.Value, Name: s.Name, Code: rune(s.Type)}
+ i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
+ if i < len(addrs) {
+ sym.Size = int64(addrs[i] - s.Value)
+ }
+ syms = append(syms, sym)
+ }
+
+ return syms
+}
diff --git a/src/cmd/objdump/Makefile b/src/cmd/objdump/Makefile
new file mode 100644
index 000000000..1b66c26ba
--- /dev/null
+++ b/src/cmd/objdump/Makefile
@@ -0,0 +1,10 @@
+all: x86.go armasm.go
+
+x86.go: bundle
+ ./bundle -p main -x x86_ rsc.io/x86/x86asm | gofmt >x86.go
+
+armasm.go: bundle
+ ./bundle -p main -x arm_ rsc.io/arm/armasm | gofmt >armasm.go
+
+bundle:
+ go build -o bundle code.google.com/p/rsc/cmd/bundle
diff --git a/src/cmd/objdump/armasm.go b/src/cmd/objdump/armasm.go
new file mode 100644
index 000000000..764a3689e
--- /dev/null
+++ b/src/cmd/objdump/armasm.go
@@ -0,0 +1,10821 @@
+// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
+// bundle -p main -x arm_ rsc.io/arm/armasm
+
+/* decode.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// An instFormat describes the format of an instruction encoding.
+// An instruction with 32-bit value x matches the format if x&mask == value
+// and the condition matches.
+// The condition matches if x>>28 == 0xF && value>>28==0xF
+// or if x>>28 != 0xF and value>>28 == 0.
+// If x matches the format, then the rest of the fields describe how to interpret x.
+// The opBits describe bits that should be extracted from x and added to the opcode.
+// For example opBits = 0x1234 means that the value
+// (2 bits at offset 1) followed by (4 bits at offset 3)
+// should be added to op.
+// Finally the args describe how to decode the instruction arguments.
+// args is stored as a fixed-size array; if there are fewer than len(args) arguments,
+// args[i] == 0 marks the end of the argument list.
+type arm_instFormat struct {
+ mask uint32
+ value uint32
+ priority int8
+ op arm_Op
+ opBits uint64
+ args arm_instArgs
+}
+
+type arm_instArgs [4]arm_instArg
+
+var (
+ arm_errMode = fmt.Errorf("unsupported execution mode")
+ arm_errShort = fmt.Errorf("truncated instruction")
+ arm_errUnknown = fmt.Errorf("unknown instruction")
+)
+
+var arm_decoderCover []bool
+
+// Decode decodes the leading bytes in src as a single instruction.
+func arm_Decode(src []byte, mode arm_Mode) (inst arm_Inst, err error) {
+ if mode != arm_ModeARM {
+ return arm_Inst{}, arm_errMode
+ }
+ if len(src) < 4 {
+ return arm_Inst{}, arm_errShort
+ }
+
+ if arm_decoderCover == nil {
+ arm_decoderCover = make([]bool, len(arm_instFormats))
+ }
+
+ x := binary.LittleEndian.Uint32(src)
+
+ // The instFormat table contains both conditional and unconditional instructions.
+ // Considering only the top 4 bits, the conditional instructions use mask=0, value=0,
+ // while the unconditional instructions use mask=f, value=f.
+ // Prepare a version of x with the condition cleared to 0 in conditional instructions
+ // and then assume mask=f during matching.
+ const condMask = 0xf0000000
+ xNoCond := x
+ if x&condMask != condMask {
+ xNoCond &^= condMask
+ }
+ var priority int8
+Search:
+ for i := range arm_instFormats {
+ f := &arm_instFormats[i]
+ if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority {
+ continue
+ }
+ delta := uint32(0)
+ deltaShift := uint(0)
+ for opBits := f.opBits; opBits != 0; opBits >>= 16 {
+ n := uint(opBits & 0xFF)
+ off := uint((opBits >> 8) & 0xFF)
+ delta |= (x >> off) & (1<<n - 1) << deltaShift
+ deltaShift += n
+ }
+ op := f.op + arm_Op(delta)
+
+ // Special case: BKPT encodes with condition but cannot have one.
+ if op&^15 == arm_BKPT_EQ && op != arm_BKPT {
+ continue Search
+ }
+
+ var args arm_Args
+ for j, aop := range f.args {
+ if aop == 0 {
+ break
+ }
+ arg := arm_decodeArg(aop, x)
+ if arg == nil { // cannot decode argument
+ continue Search
+ }
+ args[j] = arg
+ }
+
+ arm_decoderCover[i] = true
+
+ inst = arm_Inst{
+ Op: op,
+ Args: args,
+ Enc: x,
+ Len: 4,
+ }
+ priority = f.priority
+ continue Search
+ }
+ if inst.Op != 0 {
+ return inst, nil
+ }
+ return arm_Inst{}, arm_errUnknown
+}
+
+// An instArg describes the encoding of a single argument.
+// In the names used for arguments, _p_ means +, _m_ means -,
+// _pm_ means ± (usually keyed by the U bit).
+// The _W suffix indicates a general addressing mode based on the P and W bits.
+// The _offset and _postindex suffixes force the given addressing mode.
+// The rest should be somewhat self-explanatory, at least given
+// the decodeArg function.
+type arm_instArg uint8
+
+const (
+ _ arm_instArg = iota
+ arm_arg_APSR
+ arm_arg_FPSCR
+ arm_arg_Dn_half
+ arm_arg_R1_0
+ arm_arg_R1_12
+ arm_arg_R2_0
+ arm_arg_R2_12
+ arm_arg_R_0
+ arm_arg_R_12
+ arm_arg_R_12_nzcv
+ arm_arg_R_16
+ arm_arg_R_16_WB
+ arm_arg_R_8
+ arm_arg_R_rotate
+ arm_arg_R_shift_R
+ arm_arg_R_shift_imm
+ arm_arg_SP
+ arm_arg_Sd
+ arm_arg_Sd_Dd
+ arm_arg_Dd_Sd
+ arm_arg_Sm
+ arm_arg_Sm_Dm
+ arm_arg_Sn
+ arm_arg_Sn_Dn
+ arm_arg_const
+ arm_arg_endian
+ arm_arg_fbits
+ arm_arg_fp_0
+ arm_arg_imm24
+ arm_arg_imm5
+ arm_arg_imm5_32
+ arm_arg_imm5_nz
+ arm_arg_imm_12at8_4at0
+ arm_arg_imm_4at16_12at0
+ arm_arg_imm_vfp
+ arm_arg_label24
+ arm_arg_label24H
+ arm_arg_label_m_12
+ arm_arg_label_p_12
+ arm_arg_label_pm_12
+ arm_arg_label_pm_4_4
+ arm_arg_lsb_width
+ arm_arg_mem_R
+ arm_arg_mem_R_pm_R_W
+ arm_arg_mem_R_pm_R_postindex
+ arm_arg_mem_R_pm_R_shift_imm_W
+ arm_arg_mem_R_pm_R_shift_imm_offset
+ arm_arg_mem_R_pm_R_shift_imm_postindex
+ arm_arg_mem_R_pm_imm12_W
+ arm_arg_mem_R_pm_imm12_offset
+ arm_arg_mem_R_pm_imm12_postindex
+ arm_arg_mem_R_pm_imm8_W
+ arm_arg_mem_R_pm_imm8_postindex
+ arm_arg_mem_R_pm_imm8at0_offset
+ arm_arg_option
+ arm_arg_registers
+ arm_arg_registers1
+ arm_arg_registers2
+ arm_arg_satimm4
+ arm_arg_satimm5
+ arm_arg_satimm4m1
+ arm_arg_satimm5m1
+ arm_arg_widthm1
+)
+
+// decodeArg decodes the arg described by aop from the instruction bits x.
+// It returns nil if x cannot be decoded according to aop.
+func arm_decodeArg(aop arm_instArg, x uint32) arm_Arg {
+ switch aop {
+ default:
+ return nil
+
+ case arm_arg_APSR:
+ return arm_APSR
+ case arm_arg_FPSCR:
+ return arm_FPSCR
+
+ case arm_arg_R_0:
+ return arm_Reg(x & (1<<4 - 1))
+ case arm_arg_R_8:
+ return arm_Reg((x >> 8) & (1<<4 - 1))
+ case arm_arg_R_12:
+ return arm_Reg((x >> 12) & (1<<4 - 1))
+ case arm_arg_R_16:
+ return arm_Reg((x >> 16) & (1<<4 - 1))
+
+ case arm_arg_R_12_nzcv:
+ r := arm_Reg((x >> 12) & (1<<4 - 1))
+ if r == arm_R15 {
+ return arm_APSR_nzcv
+ }
+ return r
+
+ case arm_arg_R_16_WB:
+ mode := arm_AddrLDM
+ if (x>>21)&1 != 0 {
+ mode = arm_AddrLDM_WB
+ }
+ return arm_Mem{Base: arm_Reg((x >> 16) & (1<<4 - 1)), Mode: mode}
+
+ case arm_arg_R_rotate:
+ Rm := arm_Reg(x & (1<<4 - 1))
+ typ, count := arm_decodeShift(x)
+ // ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
+ if typ == arm_RotateRightExt {
+ return arm_Reg(Rm)
+ }
+ return arm_RegShift{Rm, typ, uint8(count)}
+
+ case arm_arg_R_shift_R:
+ Rm := arm_Reg(x & (1<<4 - 1))
+ Rs := arm_Reg((x >> 8) & (1<<4 - 1))
+ typ := arm_Shift((x >> 5) & (1<<2 - 1))
+ return arm_RegShiftReg{Rm, typ, Rs}
+
+ case arm_arg_R_shift_imm:
+ Rm := arm_Reg(x & (1<<4 - 1))
+ typ, count := arm_decodeShift(x)
+ if typ == arm_ShiftLeft && count == 0 {
+ return arm_Reg(Rm)
+ }
+ return arm_RegShift{Rm, typ, uint8(count)}
+
+ case arm_arg_R1_0:
+ return arm_Reg((x & (1<<4 - 1)))
+ case arm_arg_R1_12:
+ return arm_Reg(((x >> 12) & (1<<4 - 1)))
+ case arm_arg_R2_0:
+ return arm_Reg((x & (1<<4 - 1)) | 1)
+ case arm_arg_R2_12:
+ return arm_Reg(((x >> 12) & (1<<4 - 1)) | 1)
+
+ case arm_arg_SP:
+ return arm_SP
+
+ case arm_arg_Sd_Dd:
+ v := (x >> 12) & (1<<4 - 1)
+ vx := (x >> 22) & 1
+ sz := (x >> 8) & 1
+ if sz != 0 {
+ return arm_D0 + arm_Reg(vx<<4+v)
+ } else {
+ return arm_S0 + arm_Reg(v<<1+vx)
+ }
+
+ case arm_arg_Dd_Sd:
+ return arm_decodeArg(arm_arg_Sd_Dd, x^(1<<8))
+
+ case arm_arg_Sd:
+ v := (x >> 12) & (1<<4 - 1)
+ vx := (x >> 22) & 1
+ return arm_S0 + arm_Reg(v<<1+vx)
+
+ case arm_arg_Sm_Dm:
+ v := (x >> 0) & (1<<4 - 1)
+ vx := (x >> 5) & 1
+ sz := (x >> 8) & 1
+ if sz != 0 {
+ return arm_D0 + arm_Reg(vx<<4+v)
+ } else {
+ return arm_S0 + arm_Reg(v<<1+vx)
+ }
+
+ case arm_arg_Sm:
+ v := (x >> 0) & (1<<4 - 1)
+ vx := (x >> 5) & 1
+ return arm_S0 + arm_Reg(v<<1+vx)
+
+ case arm_arg_Dn_half:
+ v := (x >> 16) & (1<<4 - 1)
+ vx := (x >> 7) & 1
+ return arm_RegX{arm_D0 + arm_Reg(vx<<4+v), int((x >> 21) & 1)}
+
+ case arm_arg_Sn_Dn:
+ v := (x >> 16) & (1<<4 - 1)
+ vx := (x >> 7) & 1
+ sz := (x >> 8) & 1
+ if sz != 0 {
+ return arm_D0 + arm_Reg(vx<<4+v)
+ } else {
+ return arm_S0 + arm_Reg(v<<1+vx)
+ }
+
+ case arm_arg_Sn:
+ v := (x >> 16) & (1<<4 - 1)
+ vx := (x >> 7) & 1
+ return arm_S0 + arm_Reg(v<<1+vx)
+
+ case arm_arg_const:
+ v := x & (1<<8 - 1)
+ rot := (x >> 8) & (1<<4 - 1) * 2
+ if rot > 0 && v&3 == 0 {
+ // could rotate less
+ return arm_ImmAlt{uint8(v), uint8(rot)}
+ }
+ if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v {
+ // could wrap around to rot==0.
+ return arm_ImmAlt{uint8(v), uint8(rot)}
+ }
+ return arm_Imm(v>>rot | v<<(32-rot))
+
+ case arm_arg_endian:
+ return arm_Endian((x >> 9) & 1)
+
+ case arm_arg_fbits:
+ return arm_Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1))
+
+ case arm_arg_fp_0:
+ return arm_Imm(0)
+
+ case arm_arg_imm24:
+ return arm_Imm(x & (1<<24 - 1))
+
+ case arm_arg_imm5:
+ return arm_Imm((x >> 7) & (1<<5 - 1))
+
+ case arm_arg_imm5_32:
+ x = (x >> 7) & (1<<5 - 1)
+ if x == 0 {
+ x = 32
+ }
+ return arm_Imm(x)
+
+ case arm_arg_imm5_nz:
+ x = (x >> 7) & (1<<5 - 1)
+ if x == 0 {
+ return nil
+ }
+ return arm_Imm(x)
+
+ case arm_arg_imm_4at16_12at0:
+ return arm_Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1))
+
+ case arm_arg_imm_12at8_4at0:
+ return arm_Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1))
+
+ case arm_arg_imm_vfp:
+ x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1)
+ return arm_Imm(x)
+
+ case arm_arg_label24:
+ imm := (x & (1<<24 - 1)) << 2
+ return arm_PCRel(int32(imm<<6) >> 6)
+
+ case arm_arg_label24H:
+ h := (x >> 24) & 1
+ imm := (x&(1<<24-1))<<2 | h<<1
+ return arm_PCRel(int32(imm<<6) >> 6)
+
+ case arm_arg_label_m_12:
+ d := int32(x & (1<<12 - 1))
+ return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(-d)}
+
+ case arm_arg_label_p_12:
+ d := int32(x & (1<<12 - 1))
+ return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)}
+
+ case arm_arg_label_pm_12:
+ d := int32(x & (1<<12 - 1))
+ u := (x >> 23) & 1
+ if u == 0 {
+ d = -d
+ }
+ return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)}
+
+ case arm_arg_label_pm_4_4:
+ d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
+ u := (x >> 23) & 1
+ if u == 0 {
+ d = -d
+ }
+ return arm_PCRel(d)
+
+ case arm_arg_lsb_width:
+ lsb := (x >> 7) & (1<<5 - 1)
+ msb := (x >> 16) & (1<<5 - 1)
+ if msb < lsb || msb >= 32 {
+ return nil
+ }
+ return arm_Imm(msb + 1 - lsb)
+
+ case arm_arg_mem_R:
+ Rn := arm_Reg((x >> 16) & (1<<4 - 1))
+ return arm_Mem{Base: Rn, Mode: arm_AddrOffset}
+
+ case arm_arg_mem_R_pm_R_postindex:
+ // Treat [<Rn>],+/-<Rm> like [<Rn>,+/-<Rm>{,<shift>}]{!}
+ // by forcing shift bits to <<0 and P=0, W=0 (postindex=true).
+ return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21))
+
+ case arm_arg_mem_R_pm_R_W:
+ // Treat [<Rn>,+/-<Rm>]{!} like [<Rn>,+/-<Rm>{,<shift>}]{!}
+ // by forcing shift bits to <<0.
+ return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5))
+
+ case arm_arg_mem_R_pm_R_shift_imm_offset:
+ // Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
+ // by forcing P=1, W=0 (index=false, wback=false).
+ return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24)
+
+ case arm_arg_mem_R_pm_R_shift_imm_postindex:
+ // Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
+ // by forcing P=0, W=0 (postindex=true).
+ return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21))
+
+ case arm_arg_mem_R_pm_R_shift_imm_W:
+ Rn := arm_Reg((x >> 16) & (1<<4 - 1))
+ Rm := arm_Reg(x & (1<<4 - 1))
+ typ, count := arm_decodeShift(x)
+ u := (x >> 23) & 1
+ w := (x >> 21) & 1
+ p := (x >> 24) & 1
+ if p == 0 && w == 1 {
+ return nil
+ }
+ sign := int8(+1)
+ if u == 0 {
+ sign = -1
+ }
+ mode := arm_AddrMode(uint8(p<<1) | uint8(w^1))
+ return arm_Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count}
+
+ case arm_arg_mem_R_pm_imm12_offset:
+ // Treat [<Rn>,#+/-<imm12>] like [<Rn>{,#+/-<imm12>}]{!}
+ // by forcing P=1, W=0 (index=false, wback=false).
+ return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24)
+
+ case arm_arg_mem_R_pm_imm12_postindex:
+ // Treat [<Rn>],#+/-<imm12> like [<Rn>{,#+/-<imm12>}]{!}
+ // by forcing P=0, W=0 (postindex=true).
+ return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21))
+
+ case arm_arg_mem_R_pm_imm12_W:
+ Rn := arm_Reg((x >> 16) & (1<<4 - 1))
+ u := (x >> 23) & 1
+ w := (x >> 21) & 1
+ p := (x >> 24) & 1
+ if p == 0 && w == 1 {
+ return nil
+ }
+ sign := int8(+1)
+ if u == 0 {
+ sign = -1
+ }
+ imm := int16(x & (1<<12 - 1))
+ mode := arm_AddrMode(uint8(p<<1) | uint8(w^1))
+ return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
+
+ case arm_arg_mem_R_pm_imm8_postindex:
+ // Treat [<Rn>],#+/-<imm8> like [<Rn>{,#+/-<imm8>}]{!}
+ // by forcing P=0, W=0 (postindex=true).
+ return arm_decodeArg(arm_arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21))
+
+ case arm_arg_mem_R_pm_imm8_W:
+ Rn := arm_Reg((x >> 16) & (1<<4 - 1))
+ u := (x >> 23) & 1
+ w := (x >> 21) & 1
+ p := (x >> 24) & 1
+ if p == 0 && w == 1 {
+ return nil
+ }
+ sign := int8(+1)
+ if u == 0 {
+ sign = -1
+ }
+ imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
+ mode := arm_AddrMode(uint8(p<<1) | uint8(w^1))
+ return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
+
+ case arm_arg_mem_R_pm_imm8at0_offset:
+ Rn := arm_Reg((x >> 16) & (1<<4 - 1))
+ u := (x >> 23) & 1
+ sign := int8(+1)
+ if u == 0 {
+ sign = -1
+ }
+ imm := int16(x&(1<<8-1)) << 2
+ return arm_Mem{Base: Rn, Mode: arm_AddrOffset, Offset: int16(sign) * imm}
+
+ case arm_arg_option:
+ return arm_Imm(x & (1<<4 - 1))
+
+ case arm_arg_registers:
+ return arm_RegList(x & (1<<16 - 1))
+
+ case arm_arg_registers2:
+ x &= 1<<16 - 1
+ n := 0
+ for i := 0; i < 16; i++ {
+ if x>>uint(i)&1 != 0 {
+ n++
+ }
+ }
+ if n < 2 {
+ return nil
+ }
+ return arm_RegList(x)
+
+ case arm_arg_registers1:
+ Rt := (x >> 12) & (1<<4 - 1)
+ return arm_RegList(1 << Rt)
+
+ case arm_arg_satimm4:
+ return arm_Imm((x >> 16) & (1<<4 - 1))
+
+ case arm_arg_satimm5:
+ return arm_Imm((x >> 16) & (1<<5 - 1))
+
+ case arm_arg_satimm4m1:
+ return arm_Imm((x>>16)&(1<<4-1) + 1)
+
+ case arm_arg_satimm5m1:
+ return arm_Imm((x>>16)&(1<<5-1) + 1)
+
+ case arm_arg_widthm1:
+ return arm_Imm((x>>16)&(1<<5-1) + 1)
+
+ }
+}
+
+// decodeShift decodes the shift-by-immediate encoded in x.
+func arm_decodeShift(x uint32) (arm_Shift, uint8) {
+ count := (x >> 7) & (1<<5 - 1)
+ typ := arm_Shift((x >> 5) & (1<<2 - 1))
+ switch typ {
+ case arm_ShiftRight, arm_ShiftRightSigned:
+ if count == 0 {
+ count = 32
+ }
+ case arm_RotateRight:
+ if count == 0 {
+ typ = arm_RotateRightExt
+ count = 1
+ }
+ }
+ return typ, uint8(count)
+}
+
+/* gnu.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var arm_saveDot = strings.NewReplacer(
+ ".F16", "_dot_F16",
+ ".F32", "_dot_F32",
+ ".F64", "_dot_F64",
+ ".S32", "_dot_S32",
+ ".U32", "_dot_U32",
+ ".FXS", "_dot_S",
+ ".FXU", "_dot_U",
+ ".32", "_dot_32",
+)
+
+// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
+// This form typically matches the syntax defined in the ARM Reference Manual.
+func arm_GNUSyntax(inst arm_Inst) string {
+ var buf bytes.Buffer
+ op := inst.Op.String()
+ op = arm_saveDot.Replace(op)
+ op = strings.Replace(op, ".", "", -1)
+ op = strings.Replace(op, "_dot_", ".", -1)
+ op = strings.ToLower(op)
+ buf.WriteString(op)
+ sep := " "
+ for i, arg := range inst.Args {
+ if arg == nil {
+ break
+ }
+ text := arm_gnuArg(&inst, i, arg)
+ if text == "" {
+ continue
+ }
+ buf.WriteString(sep)
+ sep = ", "
+ buf.WriteString(text)
+ }
+ return buf.String()
+}
+
+func arm_gnuArg(inst *arm_Inst, argIndex int, arg arm_Arg) string {
+ switch inst.Op &^ 15 {
+ case arm_LDRD_EQ, arm_LDREXD_EQ, arm_STRD_EQ:
+ if argIndex == 1 {
+ // second argument in consecutive pair not printed
+ return ""
+ }
+ case arm_STREXD_EQ:
+ if argIndex == 2 {
+ // second argument in consecutive pair not printed
+ return ""
+ }
+ }
+
+ switch arg := arg.(type) {
+ case arm_Imm:
+ switch inst.Op &^ 15 {
+ case arm_BKPT_EQ:
+ return fmt.Sprintf("%#04x", uint32(arg))
+ case arm_SVC_EQ:
+ return fmt.Sprintf("%#08x", uint32(arg))
+ }
+ return fmt.Sprintf("#%d", int32(arg))
+
+ case arm_ImmAlt:
+ return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot)
+
+ case arm_Mem:
+ R := arm_gnuArg(inst, -1, arg.Base)
+ X := ""
+ if arg.Sign != 0 {
+ X = ""
+ if arg.Sign < 0 {
+ X = "-"
+ }
+ X += arm_gnuArg(inst, -1, arg.Index)
+ if arg.Shift == arm_ShiftLeft && arg.Count == 0 {
+ // nothing
+ } else if arg.Shift == arm_RotateRightExt {
+ X += ", rrx"
+ } else {
+ X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count)
+ }
+ } else {
+ X = fmt.Sprintf("#%d", arg.Offset)
+ }
+
+ switch arg.Mode {
+ case arm_AddrOffset:
+ if X == "#0" {
+ return fmt.Sprintf("[%s]", R)
+ }
+ return fmt.Sprintf("[%s, %s]", R, X)
+ case arm_AddrPreIndex:
+ return fmt.Sprintf("[%s, %s]!", R, X)
+ case arm_AddrPostIndex:
+ return fmt.Sprintf("[%s], %s", R, X)
+ case arm_AddrLDM:
+ if X == "#0" {
+ return R
+ }
+ case arm_AddrLDM_WB:
+ if X == "#0" {
+ return R + "!"
+ }
+ }
+ return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X)
+
+ case arm_PCRel:
+ return fmt.Sprintf(".%+#x", int32(arg)+4)
+
+ case arm_Reg:
+ switch inst.Op &^ 15 {
+ case arm_LDREX_EQ:
+ if argIndex == 0 {
+ return fmt.Sprintf("r%d", int32(arg))
+ }
+ }
+ switch arg {
+ case arm_R10:
+ return "sl"
+ case arm_R11:
+ return "fp"
+ case arm_R12:
+ return "ip"
+ }
+
+ case arm_RegList:
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "{")
+ sep := ""
+ for i := 0; i < 16; i++ {
+ if arg&(1<<uint(i)) != 0 {
+ fmt.Fprintf(&buf, "%s%s", sep, arm_gnuArg(inst, -1, arm_Reg(i)))
+ sep = ", "
+ }
+ }
+ fmt.Fprintf(&buf, "}")
+ return buf.String()
+
+ case arm_RegShift:
+ if arg.Shift == arm_ShiftLeft && arg.Count == 0 {
+ return arm_gnuArg(inst, -1, arg.Reg)
+ }
+ if arg.Shift == arm_RotateRightExt {
+ return arm_gnuArg(inst, -1, arg.Reg) + ", rrx"
+ }
+ return fmt.Sprintf("%s, %s #%d", arm_gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arg.Count)
+
+ case arm_RegShiftReg:
+ return fmt.Sprintf("%s, %s %s", arm_gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arm_gnuArg(inst, -1, arg.RegCount))
+
+ }
+ return strings.ToLower(arg.String())
+}
+
+/* inst.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A Mode is an instruction execution mode.
+type arm_Mode int
+
+const (
+ _ arm_Mode = iota
+ arm_ModeARM
+ arm_ModeThumb
+)
+
+func (m arm_Mode) String() string {
+ switch m {
+ case arm_ModeARM:
+ return "ARM"
+ case arm_ModeThumb:
+ return "Thumb"
+ }
+ return fmt.Sprintf("Mode(%d)", int(m))
+}
+
+// An Op is an ARM opcode.
+type arm_Op uint16
+
+// NOTE: The actual Op values are defined in tables.go.
+// They are chosen to simplify instruction decoding and
+// are not a dense packing from 0 to N, although the
+// density is high, probably at least 90%.
+
+func (op arm_Op) String() string {
+ if op >= arm_Op(len(arm_opstr)) || arm_opstr[op] == "" {
+ return fmt.Sprintf("Op(%d)", int(op))
+ }
+ return arm_opstr[op]
+}
+
+// An Inst is a single instruction.
+type arm_Inst struct {
+ Op arm_Op // Opcode mnemonic
+ Enc uint32 // Raw encoding bits.
+ Len int // Length of encoding in bytes.
+ Args arm_Args // Instruction arguments, in ARM manual order.
+}
+
+func (i arm_Inst) String() string {
+ var buf bytes.Buffer
+ buf.WriteString(i.Op.String())
+ for j, arg := range i.Args {
+ if arg == nil {
+ break
+ }
+ if j == 0 {
+ buf.WriteString(" ")
+ } else {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(arg.String())
+ }
+ return buf.String()
+}
+
+// An Args holds the instruction arguments.
+// If an instruction has fewer than 4 arguments,
+// the final elements in the array are nil.
+type arm_Args [4]arm_Arg
+
+// An Arg is a single instruction argument, one of these types:
+// Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg.
+type arm_Arg interface {
+ IsArg()
+ String() string
+}
+
+type arm_Float32Imm float32
+
+func (arm_Float32Imm) IsArg() {}
+
+func (f arm_Float32Imm) String() string {
+ return fmt.Sprintf("#%v", float32(f))
+}
+
+type arm_Float64Imm float32
+
+func (arm_Float64Imm) IsArg() {}
+
+func (f arm_Float64Imm) String() string {
+ return fmt.Sprintf("#%v", float64(f))
+}
+
+// An Imm is an integer constant.
+type arm_Imm uint32
+
+func (arm_Imm) IsArg() {}
+
+func (i arm_Imm) String() string {
+ return fmt.Sprintf("#%#x", uint32(i))
+}
+
+// A ImmAlt is an alternate encoding of an integer constant.
+type arm_ImmAlt struct {
+ Val uint8
+ Rot uint8
+}
+
+func (arm_ImmAlt) IsArg() {}
+
+func (i arm_ImmAlt) Imm() arm_Imm {
+ v := uint32(i.Val)
+ r := uint(i.Rot)
+ return arm_Imm(v>>r | v<<(32-r))
+}
+
+func (i arm_ImmAlt) String() string {
+ return fmt.Sprintf("#%#x, %d", i.Val, i.Rot)
+}
+
+// A Label is a text (code) address.
+type arm_Label uint32
+
+func (arm_Label) IsArg() {}
+
+func (i arm_Label) String() string {
+ return fmt.Sprintf("%#x", uint32(i))
+}
+
+// A Reg is a single register.
+// The zero value denotes R0, not the absence of a register.
+type arm_Reg uint8
+
+const (
+ arm_R0 arm_Reg = iota
+ arm_R1
+ arm_R2
+ arm_R3
+ arm_R4
+ arm_R5
+ arm_R6
+ arm_R7
+ arm_R8
+ arm_R9
+ arm_R10
+ arm_R11
+ arm_R12
+ arm_R13
+ arm_R14
+ arm_R15
+
+ arm_S0
+ arm_S1
+ arm_S2
+ arm_S3
+ arm_S4
+ arm_S5
+ arm_S6
+ arm_S7
+ arm_S8
+ arm_S9
+ arm_S10
+ arm_S11
+ arm_S12
+ arm_S13
+ arm_S14
+ arm_S15
+ arm_S16
+ arm_S17
+ arm_S18
+ arm_S19
+ arm_S20
+ arm_S21
+ arm_S22
+ arm_S23
+ arm_S24
+ arm_S25
+ arm_S26
+ arm_S27
+ arm_S28
+ arm_S29
+ arm_S30
+ arm_S31
+
+ arm_D0
+ arm_D1
+ arm_D2
+ arm_D3
+ arm_D4
+ arm_D5
+ arm_D6
+ arm_D7
+ arm_D8
+ arm_D9
+ arm_D10
+ arm_D11
+ arm_D12
+ arm_D13
+ arm_D14
+ arm_D15
+ arm_D16
+ arm_D17
+ arm_D18
+ arm_D19
+ arm_D20
+ arm_D21
+ arm_D22
+ arm_D23
+ arm_D24
+ arm_D25
+ arm_D26
+ arm_D27
+ arm_D28
+ arm_D29
+ arm_D30
+ arm_D31
+
+ arm_APSR
+ arm_APSR_nzcv
+ arm_FPSCR
+
+ arm_SP = arm_R13
+ arm_LR = arm_R14
+ arm_PC = arm_R15
+)
+
+func (arm_Reg) IsArg() {}
+
+func (r arm_Reg) String() string {
+ switch r {
+ case arm_APSR:
+ return "APSR"
+ case arm_APSR_nzcv:
+ return "APSR_nzcv"
+ case arm_FPSCR:
+ return "FPSCR"
+ case arm_SP:
+ return "SP"
+ case arm_PC:
+ return "PC"
+ case arm_LR:
+ return "LR"
+ }
+ if arm_R0 <= r && r <= arm_R15 {
+ return fmt.Sprintf("R%d", int(r-arm_R0))
+ }
+ if arm_S0 <= r && r <= arm_S31 {
+ return fmt.Sprintf("S%d", int(r-arm_S0))
+ }
+ if arm_D0 <= r && r <= arm_D31 {
+ return fmt.Sprintf("D%d", int(r-arm_D0))
+ }
+ return fmt.Sprintf("Reg(%d)", int(r))
+}
+
+// A RegX represents a fraction of a multi-value register.
+// The Index field specifies the index number,
+// but the size of the fraction is not specified.
+// It must be inferred from the instruction and the register type.
+// For example, in a VMOV instruction, RegX{D5, 1} represents
+// the top 32 bits of the 64-bit D5 register.
+type arm_RegX struct {
+ Reg arm_Reg
+ Index int
+}
+
+func (arm_RegX) IsArg() {}
+
+func (r arm_RegX) String() string {
+ return fmt.Sprintf("%s[%d]", r.Reg, r.Index)
+}
+
+// A RegList is a register list.
+// Bits at indexes x = 0 through 15 indicate whether the corresponding Rx register is in the list.
+type arm_RegList uint16
+
+func (arm_RegList) IsArg() {}
+
+func (r arm_RegList) String() string {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "{")
+ sep := ""
+ for i := 0; i < 16; i++ {
+ if r&(1<<uint(i)) != 0 {
+ fmt.Fprintf(&buf, "%s%s", sep, arm_Reg(i).String())
+ sep = ","
+ }
+ }
+ fmt.Fprintf(&buf, "}")
+ return buf.String()
+}
+
+// An Endian is the argument to the SETEND instruction.
+type arm_Endian uint8
+
+const (
+ arm_LittleEndian arm_Endian = 0
+ arm_BigEndian arm_Endian = 1
+)
+
+func (arm_Endian) IsArg() {}
+
+func (e arm_Endian) String() string {
+ if e != 0 {
+ return "BE"
+ }
+ return "LE"
+}
+
+// A Shift describes an ARM shift operation.
+type arm_Shift uint8
+
+const (
+ arm_ShiftLeft arm_Shift = 0 // left shift
+ arm_ShiftRight arm_Shift = 1 // logical (unsigned) right shift
+ arm_ShiftRightSigned arm_Shift = 2 // arithmetic (signed) right shift
+ arm_RotateRight arm_Shift = 3 // right rotate
+ arm_RotateRightExt arm_Shift = 4 // right rotate through carry (Count will always be 1)
+)
+
+var arm_shiftName = [...]string{
+ "LSL", "LSR", "ASR", "ROR", "RRX",
+}
+
+func (s arm_Shift) String() string {
+ if s < 5 {
+ return arm_shiftName[s]
+ }
+ return fmt.Sprintf("Shift(%d)", int(s))
+}
+
+// A RegShift is a register shifted by a constant.
+type arm_RegShift struct {
+ Reg arm_Reg
+ Shift arm_Shift
+ Count uint8
+}
+
+func (arm_RegShift) IsArg() {}
+
+func (r arm_RegShift) String() string {
+ return fmt.Sprintf("%s %s #%d", r.Reg, r.Shift, r.Count)
+}
+
+// A RegShiftReg is a register shifted by a register.
+type arm_RegShiftReg struct {
+ Reg arm_Reg
+ Shift arm_Shift
+ RegCount arm_Reg
+}
+
+func (arm_RegShiftReg) IsArg() {}
+
+func (r arm_RegShiftReg) String() string {
+ return fmt.Sprintf("%s %s %s", r.Reg, r.Shift, r.RegCount)
+}
+
+// A PCRel describes a memory address (usually a code label)
+// as a distance relative to the program counter.
+// TODO(rsc): Define which program counter (PC+4? PC+8? PC?).
+type arm_PCRel int32
+
+func (arm_PCRel) IsArg() {}
+
+func (r arm_PCRel) String() string {
+ return fmt.Sprintf("PC%+#x", int32(r))
+}
+
+// An AddrMode is an ARM addressing mode.
+type arm_AddrMode uint8
+
+const (
+ _ arm_AddrMode = iota
+ arm_AddrPostIndex // [R], X – use address R, set R = R + X
+ arm_AddrPreIndex // [R, X]! – use address R + X, set R = R + X
+ arm_AddrOffset // [R, X] – use address R + X
+ arm_AddrLDM // R – [R] but formats as R, for LDM/STM only
+ arm_AddrLDM_WB // R! - [R], X where X is instruction-specific amount, for LDM/STM only
+)
+
+// A Mem is a memory reference made up of a base R and index expression X.
+// The effective memory address is R or R+X depending on AddrMode.
+// The index expression is X = Sign*(Index Shift Count) + Offset,
+// but in any instruction either Sign = 0 or Offset = 0.
+type arm_Mem struct {
+ Base arm_Reg
+ Mode arm_AddrMode
+ Sign int8
+ Index arm_Reg
+ Shift arm_Shift
+ Count uint8
+ Offset int16
+}
+
+func (arm_Mem) IsArg() {}
+
+func (m arm_Mem) String() string {
+ R := m.Base.String()
+ X := ""
+ if m.Sign != 0 {
+ X = "+"
+ if m.Sign < 0 {
+ X = "-"
+ }
+ X += m.Index.String()
+ if m.Shift != arm_ShiftLeft || m.Count != 0 {
+ X += fmt.Sprintf(", %s #%d", m.Shift, m.Count)
+ }
+ } else {
+ X = fmt.Sprintf("#%d", m.Offset)
+ }
+
+ switch m.Mode {
+ case arm_AddrOffset:
+ if X == "#0" {
+ return fmt.Sprintf("[%s]", R)
+ }
+ return fmt.Sprintf("[%s, %s]", R, X)
+ case arm_AddrPreIndex:
+ return fmt.Sprintf("[%s, %s]!", R, X)
+ case arm_AddrPostIndex:
+ return fmt.Sprintf("[%s], %s", R, X)
+ case arm_AddrLDM:
+ if X == "#0" {
+ return R
+ }
+ case arm_AddrLDM_WB:
+ if X == "#0" {
+ return R + "!"
+ }
+ }
+ return fmt.Sprintf("[%s Mode(%d) %s]", R, int(m.Mode), X)
+}
+
+/* plan9x.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// plan9Syntax returns the Go assembler syntax for the instruction.
+// The syntax was originally defined by Plan 9.
+// The pc is the program counter of the instruction, used for expanding
+// PC-relative addresses into absolute ones.
+// The symname function queries the symbol table for the program
+// being disassembled. Given a target address it returns the name and base
+// address of the symbol containing the target, if any; otherwise it returns "", 0.
+// The reader r should read from the text segment using text addresses
+// as offsets; it is used to display pc-relative loads as constant loads.
+func arm_plan9Syntax(inst arm_Inst, pc uint64, symname func(uint64) (string, uint64), text io.ReaderAt) string {
+ if symname == nil {
+ symname = func(uint64) (string, uint64) { return "", 0 }
+ }
+
+ var args []string
+ for _, a := range inst.Args {
+ if a == nil {
+ break
+ }
+ args = append(args, arm_plan9Arg(&inst, pc, symname, a))
+ }
+
+ op := inst.Op.String()
+
+ switch inst.Op &^ 15 {
+ case arm_LDR_EQ, arm_LDRB_EQ, arm_LDRH_EQ:
+ // Check for RET
+ reg, _ := inst.Args[0].(arm_Reg)
+ mem, _ := inst.Args[1].(arm_Mem)
+ if inst.Op&^15 == arm_LDR_EQ && reg == arm_R15 && mem.Base == arm_SP && mem.Sign == 0 && mem.Mode == arm_AddrPostIndex {
+ return fmt.Sprintf("RET%s #%d", op[3:], mem.Offset)
+ }
+
+ // Check for PC-relative load.
+ if mem.Base == arm_PC && mem.Sign == 0 && mem.Mode == arm_AddrOffset && text != nil {
+ addr := uint32(pc) + 8 + uint32(mem.Offset)
+ buf := make([]byte, 4)
+ switch inst.Op &^ 15 {
+ case arm_LDRB_EQ:
+ if _, err := text.ReadAt(buf[:1], int64(addr)); err != nil {
+ break
+ }
+ args[1] = fmt.Sprintf("$%#x", buf[0])
+
+ case arm_LDRH_EQ:
+ if _, err := text.ReadAt(buf[:2], int64(addr)); err != nil {
+ break
+ }
+ args[1] = fmt.Sprintf("$%#x", binary.LittleEndian.Uint16(buf))
+
+ case arm_LDR_EQ:
+ if _, err := text.ReadAt(buf, int64(addr)); err != nil {
+ break
+ }
+ x := binary.LittleEndian.Uint32(buf)
+ if s, base := symname(uint64(x)); s != "" && uint64(x) == base {
+ args[1] = fmt.Sprintf("$%s(SB)", s)
+ } else {
+ args[1] = fmt.Sprintf("$%#x", x)
+ }
+ }
+ }
+ }
+
+ // Move addressing mode into opcode suffix.
+ suffix := ""
+ switch inst.Op &^ 15 {
+ case arm_LDR_EQ, arm_LDRB_EQ, arm_LDRH_EQ, arm_STR_EQ, arm_STRB_EQ, arm_STRH_EQ:
+ mem, _ := inst.Args[1].(arm_Mem)
+ switch mem.Mode {
+ case arm_AddrOffset, arm_AddrLDM:
+ // no suffix
+ case arm_AddrPreIndex, arm_AddrLDM_WB:
+ suffix = ".W"
+ case arm_AddrPostIndex:
+ suffix = ".P"
+ }
+ off := ""
+ if mem.Offset != 0 {
+ off = fmt.Sprintf("%#x", mem.Offset)
+ }
+ base := fmt.Sprintf("(R%d)", int(mem.Base))
+ index := ""
+ if mem.Sign != 0 {
+ sign := ""
+ if mem.Sign < 0 {
+ sign = ""
+ }
+ shift := ""
+ if mem.Count != 0 {
+ shift = fmt.Sprintf("%s%d", arm_plan9Shift[mem.Shift], mem.Count)
+ }
+ index = fmt.Sprintf("(%sR%d%s)", sign, int(mem.Index), shift)
+ }
+ args[1] = off + base + index
+ }
+
+ // Reverse args, placing dest last.
+ for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+ args[i], args[j] = args[j], args[i]
+ }
+
+ switch inst.Op &^ 15 {
+ case arm_MOV_EQ:
+ op = "MOVW" + op[3:]
+
+ case arm_LDR_EQ:
+ op = "MOVW" + op[3:] + suffix
+ case arm_LDRB_EQ:
+ op = "MOVB" + op[4:] + suffix
+ case arm_LDRH_EQ:
+ op = "MOVH" + op[4:] + suffix
+
+ case arm_STR_EQ:
+ op = "MOVW" + op[3:] + suffix
+ args[0], args[1] = args[1], args[0]
+ case arm_STRB_EQ:
+ op = "MOVB" + op[4:] + suffix
+ args[0], args[1] = args[1], args[0]
+ case arm_STRH_EQ:
+ op = "MOVH" + op[4:] + suffix
+ args[0], args[1] = args[1], args[0]
+ }
+
+ if args != nil {
+ op += " " + strings.Join(args, ", ")
+ }
+
+ return op
+}
+
+// assembler syntax for the various shifts.
+// @x> is a lie; the assembler uses @> 0
+// instead of @x> 1, but i wanted to be clear that it
+// was a different operation (rotate right extended, not rotate right).
+var arm_plan9Shift = []string{"<<", ">>", "->", "@>", "@x>"}
+
+func arm_plan9Arg(inst *arm_Inst, pc uint64, symname func(uint64) (string, uint64), arg arm_Arg) string {
+ switch a := arg.(type) {
+ case arm_Endian:
+
+ case arm_Imm:
+ return fmt.Sprintf("$%d", int(a))
+
+ case arm_Mem:
+
+ case arm_PCRel:
+ addr := uint32(pc) + 8 + uint32(a)
+ if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
+ return fmt.Sprintf("%s(SB)", s)
+ }
+ return fmt.Sprintf("%#x", addr)
+
+ case arm_Reg:
+ if a < 16 {
+ return fmt.Sprintf("R%d", int(a))
+ }
+
+ case arm_RegList:
+ var buf bytes.Buffer
+ start := -2
+ end := -2
+ fmt.Fprintf(&buf, "[")
+ flush := func() {
+ if start >= 0 {
+ if buf.Len() > 1 {
+ fmt.Fprintf(&buf, ",")
+ }
+ if start == end {
+ fmt.Fprintf(&buf, "R%d", start)
+ } else {
+ fmt.Fprintf(&buf, "R%d-R%d", start, end)
+ }
+ }
+ }
+ for i := 0; i < 16; i++ {
+ if a&(1<<uint(i)) != 0 {
+ if i == end+1 {
+ end++
+ continue
+ }
+ start = i
+ end = i
+ }
+ }
+ flush()
+ fmt.Fprintf(&buf, "]")
+ return buf.String()
+
+ case arm_RegShift:
+ return fmt.Sprintf("R%d%s$%d", int(a.Reg), arm_plan9Shift[a.Shift], int(a.Count))
+
+ case arm_RegShiftReg:
+ return fmt.Sprintf("R%d%sR%d", int(a.Reg), arm_plan9Shift[a.Shift], int(a.RegCount))
+ }
+ return strings.ToUpper(arg.String())
+}
+
+/* tables.go */
+
+const (
+ _ arm_Op = iota
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_ADC_EQ
+ arm_ADC_NE
+ arm_ADC_CS
+ arm_ADC_CC
+ arm_ADC_MI
+ arm_ADC_PL
+ arm_ADC_VS
+ arm_ADC_VC
+ arm_ADC_HI
+ arm_ADC_LS
+ arm_ADC_GE
+ arm_ADC_LT
+ arm_ADC_GT
+ arm_ADC_LE
+ arm_ADC
+ arm_ADC_ZZ
+ arm_ADC_S_EQ
+ arm_ADC_S_NE
+ arm_ADC_S_CS
+ arm_ADC_S_CC
+ arm_ADC_S_MI
+ arm_ADC_S_PL
+ arm_ADC_S_VS
+ arm_ADC_S_VC
+ arm_ADC_S_HI
+ arm_ADC_S_LS
+ arm_ADC_S_GE
+ arm_ADC_S_LT
+ arm_ADC_S_GT
+ arm_ADC_S_LE
+ arm_ADC_S
+ arm_ADC_S_ZZ
+ arm_ADD_EQ
+ arm_ADD_NE
+ arm_ADD_CS
+ arm_ADD_CC
+ arm_ADD_MI
+ arm_ADD_PL
+ arm_ADD_VS
+ arm_ADD_VC
+ arm_ADD_HI
+ arm_ADD_LS
+ arm_ADD_GE
+ arm_ADD_LT
+ arm_ADD_GT
+ arm_ADD_LE
+ arm_ADD
+ arm_ADD_ZZ
+ arm_ADD_S_EQ
+ arm_ADD_S_NE
+ arm_ADD_S_CS
+ arm_ADD_S_CC
+ arm_ADD_S_MI
+ arm_ADD_S_PL
+ arm_ADD_S_VS
+ arm_ADD_S_VC
+ arm_ADD_S_HI
+ arm_ADD_S_LS
+ arm_ADD_S_GE
+ arm_ADD_S_LT
+ arm_ADD_S_GT
+ arm_ADD_S_LE
+ arm_ADD_S
+ arm_ADD_S_ZZ
+ arm_AND_EQ
+ arm_AND_NE
+ arm_AND_CS
+ arm_AND_CC
+ arm_AND_MI
+ arm_AND_PL
+ arm_AND_VS
+ arm_AND_VC
+ arm_AND_HI
+ arm_AND_LS
+ arm_AND_GE
+ arm_AND_LT
+ arm_AND_GT
+ arm_AND_LE
+ arm_AND
+ arm_AND_ZZ
+ arm_AND_S_EQ
+ arm_AND_S_NE
+ arm_AND_S_CS
+ arm_AND_S_CC
+ arm_AND_S_MI
+ arm_AND_S_PL
+ arm_AND_S_VS
+ arm_AND_S_VC
+ arm_AND_S_HI
+ arm_AND_S_LS
+ arm_AND_S_GE
+ arm_AND_S_LT
+ arm_AND_S_GT
+ arm_AND_S_LE
+ arm_AND_S
+ arm_AND_S_ZZ
+ arm_ASR_EQ
+ arm_ASR_NE
+ arm_ASR_CS
+ arm_ASR_CC
+ arm_ASR_MI
+ arm_ASR_PL
+ arm_ASR_VS
+ arm_ASR_VC
+ arm_ASR_HI
+ arm_ASR_LS
+ arm_ASR_GE
+ arm_ASR_LT
+ arm_ASR_GT
+ arm_ASR_LE
+ arm_ASR
+ arm_ASR_ZZ
+ arm_ASR_S_EQ
+ arm_ASR_S_NE
+ arm_ASR_S_CS
+ arm_ASR_S_CC
+ arm_ASR_S_MI
+ arm_ASR_S_PL
+ arm_ASR_S_VS
+ arm_ASR_S_VC
+ arm_ASR_S_HI
+ arm_ASR_S_LS
+ arm_ASR_S_GE
+ arm_ASR_S_LT
+ arm_ASR_S_GT
+ arm_ASR_S_LE
+ arm_ASR_S
+ arm_ASR_S_ZZ
+ arm_B_EQ
+ arm_B_NE
+ arm_B_CS
+ arm_B_CC
+ arm_B_MI
+ arm_B_PL
+ arm_B_VS
+ arm_B_VC
+ arm_B_HI
+ arm_B_LS
+ arm_B_GE
+ arm_B_LT
+ arm_B_GT
+ arm_B_LE
+ arm_B
+ arm_B_ZZ
+ arm_BFC_EQ
+ arm_BFC_NE
+ arm_BFC_CS
+ arm_BFC_CC
+ arm_BFC_MI
+ arm_BFC_PL
+ arm_BFC_VS
+ arm_BFC_VC
+ arm_BFC_HI
+ arm_BFC_LS
+ arm_BFC_GE
+ arm_BFC_LT
+ arm_BFC_GT
+ arm_BFC_LE
+ arm_BFC
+ arm_BFC_ZZ
+ arm_BFI_EQ
+ arm_BFI_NE
+ arm_BFI_CS
+ arm_BFI_CC
+ arm_BFI_MI
+ arm_BFI_PL
+ arm_BFI_VS
+ arm_BFI_VC
+ arm_BFI_HI
+ arm_BFI_LS
+ arm_BFI_GE
+ arm_BFI_LT
+ arm_BFI_GT
+ arm_BFI_LE
+ arm_BFI
+ arm_BFI_ZZ
+ arm_BIC_EQ
+ arm_BIC_NE
+ arm_BIC_CS
+ arm_BIC_CC
+ arm_BIC_MI
+ arm_BIC_PL
+ arm_BIC_VS
+ arm_BIC_VC
+ arm_BIC_HI
+ arm_BIC_LS
+ arm_BIC_GE
+ arm_BIC_LT
+ arm_BIC_GT
+ arm_BIC_LE
+ arm_BIC
+ arm_BIC_ZZ
+ arm_BIC_S_EQ
+ arm_BIC_S_NE
+ arm_BIC_S_CS
+ arm_BIC_S_CC
+ arm_BIC_S_MI
+ arm_BIC_S_PL
+ arm_BIC_S_VS
+ arm_BIC_S_VC
+ arm_BIC_S_HI
+ arm_BIC_S_LS
+ arm_BIC_S_GE
+ arm_BIC_S_LT
+ arm_BIC_S_GT
+ arm_BIC_S_LE
+ arm_BIC_S
+ arm_BIC_S_ZZ
+ arm_BKPT_EQ
+ arm_BKPT_NE
+ arm_BKPT_CS
+ arm_BKPT_CC
+ arm_BKPT_MI
+ arm_BKPT_PL
+ arm_BKPT_VS
+ arm_BKPT_VC
+ arm_BKPT_HI
+ arm_BKPT_LS
+ arm_BKPT_GE
+ arm_BKPT_LT
+ arm_BKPT_GT
+ arm_BKPT_LE
+ arm_BKPT
+ arm_BKPT_ZZ
+ arm_BL_EQ
+ arm_BL_NE
+ arm_BL_CS
+ arm_BL_CC
+ arm_BL_MI
+ arm_BL_PL
+ arm_BL_VS
+ arm_BL_VC
+ arm_BL_HI
+ arm_BL_LS
+ arm_BL_GE
+ arm_BL_LT
+ arm_BL_GT
+ arm_BL_LE
+ arm_BL
+ arm_BL_ZZ
+ arm_BLX_EQ
+ arm_BLX_NE
+ arm_BLX_CS
+ arm_BLX_CC
+ arm_BLX_MI
+ arm_BLX_PL
+ arm_BLX_VS
+ arm_BLX_VC
+ arm_BLX_HI
+ arm_BLX_LS
+ arm_BLX_GE
+ arm_BLX_LT
+ arm_BLX_GT
+ arm_BLX_LE
+ arm_BLX
+ arm_BLX_ZZ
+ arm_BX_EQ
+ arm_BX_NE
+ arm_BX_CS
+ arm_BX_CC
+ arm_BX_MI
+ arm_BX_PL
+ arm_BX_VS
+ arm_BX_VC
+ arm_BX_HI
+ arm_BX_LS
+ arm_BX_GE
+ arm_BX_LT
+ arm_BX_GT
+ arm_BX_LE
+ arm_BX
+ arm_BX_ZZ
+ arm_BXJ_EQ
+ arm_BXJ_NE
+ arm_BXJ_CS
+ arm_BXJ_CC
+ arm_BXJ_MI
+ arm_BXJ_PL
+ arm_BXJ_VS
+ arm_BXJ_VC
+ arm_BXJ_HI
+ arm_BXJ_LS
+ arm_BXJ_GE
+ arm_BXJ_LT
+ arm_BXJ_GT
+ arm_BXJ_LE
+ arm_BXJ
+ arm_BXJ_ZZ
+ arm_CLREX
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_CLZ_EQ
+ arm_CLZ_NE
+ arm_CLZ_CS
+ arm_CLZ_CC
+ arm_CLZ_MI
+ arm_CLZ_PL
+ arm_CLZ_VS
+ arm_CLZ_VC
+ arm_CLZ_HI
+ arm_CLZ_LS
+ arm_CLZ_GE
+ arm_CLZ_LT
+ arm_CLZ_GT
+ arm_CLZ_LE
+ arm_CLZ
+ arm_CLZ_ZZ
+ arm_CMN_EQ
+ arm_CMN_NE
+ arm_CMN_CS
+ arm_CMN_CC
+ arm_CMN_MI
+ arm_CMN_PL
+ arm_CMN_VS
+ arm_CMN_VC
+ arm_CMN_HI
+ arm_CMN_LS
+ arm_CMN_GE
+ arm_CMN_LT
+ arm_CMN_GT
+ arm_CMN_LE
+ arm_CMN
+ arm_CMN_ZZ
+ arm_CMP_EQ
+ arm_CMP_NE
+ arm_CMP_CS
+ arm_CMP_CC
+ arm_CMP_MI
+ arm_CMP_PL
+ arm_CMP_VS
+ arm_CMP_VC
+ arm_CMP_HI
+ arm_CMP_LS
+ arm_CMP_GE
+ arm_CMP_LT
+ arm_CMP_GT
+ arm_CMP_LE
+ arm_CMP
+ arm_CMP_ZZ
+ arm_DBG_EQ
+ arm_DBG_NE
+ arm_DBG_CS
+ arm_DBG_CC
+ arm_DBG_MI
+ arm_DBG_PL
+ arm_DBG_VS
+ arm_DBG_VC
+ arm_DBG_HI
+ arm_DBG_LS
+ arm_DBG_GE
+ arm_DBG_LT
+ arm_DBG_GT
+ arm_DBG_LE
+ arm_DBG
+ arm_DBG_ZZ
+ arm_DMB
+ arm_DSB
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_EOR_EQ
+ arm_EOR_NE
+ arm_EOR_CS
+ arm_EOR_CC
+ arm_EOR_MI
+ arm_EOR_PL
+ arm_EOR_VS
+ arm_EOR_VC
+ arm_EOR_HI
+ arm_EOR_LS
+ arm_EOR_GE
+ arm_EOR_LT
+ arm_EOR_GT
+ arm_EOR_LE
+ arm_EOR
+ arm_EOR_ZZ
+ arm_EOR_S_EQ
+ arm_EOR_S_NE
+ arm_EOR_S_CS
+ arm_EOR_S_CC
+ arm_EOR_S_MI
+ arm_EOR_S_PL
+ arm_EOR_S_VS
+ arm_EOR_S_VC
+ arm_EOR_S_HI
+ arm_EOR_S_LS
+ arm_EOR_S_GE
+ arm_EOR_S_LT
+ arm_EOR_S_GT
+ arm_EOR_S_LE
+ arm_EOR_S
+ arm_EOR_S_ZZ
+ arm_ISB
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_LDM_EQ
+ arm_LDM_NE
+ arm_LDM_CS
+ arm_LDM_CC
+ arm_LDM_MI
+ arm_LDM_PL
+ arm_LDM_VS
+ arm_LDM_VC
+ arm_LDM_HI
+ arm_LDM_LS
+ arm_LDM_GE
+ arm_LDM_LT
+ arm_LDM_GT
+ arm_LDM_LE
+ arm_LDM
+ arm_LDM_ZZ
+ arm_LDMDA_EQ
+ arm_LDMDA_NE
+ arm_LDMDA_CS
+ arm_LDMDA_CC
+ arm_LDMDA_MI
+ arm_LDMDA_PL
+ arm_LDMDA_VS
+ arm_LDMDA_VC
+ arm_LDMDA_HI
+ arm_LDMDA_LS
+ arm_LDMDA_GE
+ arm_LDMDA_LT
+ arm_LDMDA_GT
+ arm_LDMDA_LE
+ arm_LDMDA
+ arm_LDMDA_ZZ
+ arm_LDMDB_EQ
+ arm_LDMDB_NE
+ arm_LDMDB_CS
+ arm_LDMDB_CC
+ arm_LDMDB_MI
+ arm_LDMDB_PL
+ arm_LDMDB_VS
+ arm_LDMDB_VC
+ arm_LDMDB_HI
+ arm_LDMDB_LS
+ arm_LDMDB_GE
+ arm_LDMDB_LT
+ arm_LDMDB_GT
+ arm_LDMDB_LE
+ arm_LDMDB
+ arm_LDMDB_ZZ
+ arm_LDMIB_EQ
+ arm_LDMIB_NE
+ arm_LDMIB_CS
+ arm_LDMIB_CC
+ arm_LDMIB_MI
+ arm_LDMIB_PL
+ arm_LDMIB_VS
+ arm_LDMIB_VC
+ arm_LDMIB_HI
+ arm_LDMIB_LS
+ arm_LDMIB_GE
+ arm_LDMIB_LT
+ arm_LDMIB_GT
+ arm_LDMIB_LE
+ arm_LDMIB
+ arm_LDMIB_ZZ
+ arm_LDR_EQ
+ arm_LDR_NE
+ arm_LDR_CS
+ arm_LDR_CC
+ arm_LDR_MI
+ arm_LDR_PL
+ arm_LDR_VS
+ arm_LDR_VC
+ arm_LDR_HI
+ arm_LDR_LS
+ arm_LDR_GE
+ arm_LDR_LT
+ arm_LDR_GT
+ arm_LDR_LE
+ arm_LDR
+ arm_LDR_ZZ
+ arm_LDRB_EQ
+ arm_LDRB_NE
+ arm_LDRB_CS
+ arm_LDRB_CC
+ arm_LDRB_MI
+ arm_LDRB_PL
+ arm_LDRB_VS
+ arm_LDRB_VC
+ arm_LDRB_HI
+ arm_LDRB_LS
+ arm_LDRB_GE
+ arm_LDRB_LT
+ arm_LDRB_GT
+ arm_LDRB_LE
+ arm_LDRB
+ arm_LDRB_ZZ
+ arm_LDRBT_EQ
+ arm_LDRBT_NE
+ arm_LDRBT_CS
+ arm_LDRBT_CC
+ arm_LDRBT_MI
+ arm_LDRBT_PL
+ arm_LDRBT_VS
+ arm_LDRBT_VC
+ arm_LDRBT_HI
+ arm_LDRBT_LS
+ arm_LDRBT_GE
+ arm_LDRBT_LT
+ arm_LDRBT_GT
+ arm_LDRBT_LE
+ arm_LDRBT
+ arm_LDRBT_ZZ
+ arm_LDRD_EQ
+ arm_LDRD_NE
+ arm_LDRD_CS
+ arm_LDRD_CC
+ arm_LDRD_MI
+ arm_LDRD_PL
+ arm_LDRD_VS
+ arm_LDRD_VC
+ arm_LDRD_HI
+ arm_LDRD_LS
+ arm_LDRD_GE
+ arm_LDRD_LT
+ arm_LDRD_GT
+ arm_LDRD_LE
+ arm_LDRD
+ arm_LDRD_ZZ
+ arm_LDREX_EQ
+ arm_LDREX_NE
+ arm_LDREX_CS
+ arm_LDREX_CC
+ arm_LDREX_MI
+ arm_LDREX_PL
+ arm_LDREX_VS
+ arm_LDREX_VC
+ arm_LDREX_HI
+ arm_LDREX_LS
+ arm_LDREX_GE
+ arm_LDREX_LT
+ arm_LDREX_GT
+ arm_LDREX_LE
+ arm_LDREX
+ arm_LDREX_ZZ
+ arm_LDREXB_EQ
+ arm_LDREXB_NE
+ arm_LDREXB_CS
+ arm_LDREXB_CC
+ arm_LDREXB_MI
+ arm_LDREXB_PL
+ arm_LDREXB_VS
+ arm_LDREXB_VC
+ arm_LDREXB_HI
+ arm_LDREXB_LS
+ arm_LDREXB_GE
+ arm_LDREXB_LT
+ arm_LDREXB_GT
+ arm_LDREXB_LE
+ arm_LDREXB
+ arm_LDREXB_ZZ
+ arm_LDREXD_EQ
+ arm_LDREXD_NE
+ arm_LDREXD_CS
+ arm_LDREXD_CC
+ arm_LDREXD_MI
+ arm_LDREXD_PL
+ arm_LDREXD_VS
+ arm_LDREXD_VC
+ arm_LDREXD_HI
+ arm_LDREXD_LS
+ arm_LDREXD_GE
+ arm_LDREXD_LT
+ arm_LDREXD_GT
+ arm_LDREXD_LE
+ arm_LDREXD
+ arm_LDREXD_ZZ
+ arm_LDREXH_EQ
+ arm_LDREXH_NE
+ arm_LDREXH_CS
+ arm_LDREXH_CC
+ arm_LDREXH_MI
+ arm_LDREXH_PL
+ arm_LDREXH_VS
+ arm_LDREXH_VC
+ arm_LDREXH_HI
+ arm_LDREXH_LS
+ arm_LDREXH_GE
+ arm_LDREXH_LT
+ arm_LDREXH_GT
+ arm_LDREXH_LE
+ arm_LDREXH
+ arm_LDREXH_ZZ
+ arm_LDRH_EQ
+ arm_LDRH_NE
+ arm_LDRH_CS
+ arm_LDRH_CC
+ arm_LDRH_MI
+ arm_LDRH_PL
+ arm_LDRH_VS
+ arm_LDRH_VC
+ arm_LDRH_HI
+ arm_LDRH_LS
+ arm_LDRH_GE
+ arm_LDRH_LT
+ arm_LDRH_GT
+ arm_LDRH_LE
+ arm_LDRH
+ arm_LDRH_ZZ
+ arm_LDRHT_EQ
+ arm_LDRHT_NE
+ arm_LDRHT_CS
+ arm_LDRHT_CC
+ arm_LDRHT_MI
+ arm_LDRHT_PL
+ arm_LDRHT_VS
+ arm_LDRHT_VC
+ arm_LDRHT_HI
+ arm_LDRHT_LS
+ arm_LDRHT_GE
+ arm_LDRHT_LT
+ arm_LDRHT_GT
+ arm_LDRHT_LE
+ arm_LDRHT
+ arm_LDRHT_ZZ
+ arm_LDRSB_EQ
+ arm_LDRSB_NE
+ arm_LDRSB_CS
+ arm_LDRSB_CC
+ arm_LDRSB_MI
+ arm_LDRSB_PL
+ arm_LDRSB_VS
+ arm_LDRSB_VC
+ arm_LDRSB_HI
+ arm_LDRSB_LS
+ arm_LDRSB_GE
+ arm_LDRSB_LT
+ arm_LDRSB_GT
+ arm_LDRSB_LE
+ arm_LDRSB
+ arm_LDRSB_ZZ
+ arm_LDRSBT_EQ
+ arm_LDRSBT_NE
+ arm_LDRSBT_CS
+ arm_LDRSBT_CC
+ arm_LDRSBT_MI
+ arm_LDRSBT_PL
+ arm_LDRSBT_VS
+ arm_LDRSBT_VC
+ arm_LDRSBT_HI
+ arm_LDRSBT_LS
+ arm_LDRSBT_GE
+ arm_LDRSBT_LT
+ arm_LDRSBT_GT
+ arm_LDRSBT_LE
+ arm_LDRSBT
+ arm_LDRSBT_ZZ
+ arm_LDRSH_EQ
+ arm_LDRSH_NE
+ arm_LDRSH_CS
+ arm_LDRSH_CC
+ arm_LDRSH_MI
+ arm_LDRSH_PL
+ arm_LDRSH_VS
+ arm_LDRSH_VC
+ arm_LDRSH_HI
+ arm_LDRSH_LS
+ arm_LDRSH_GE
+ arm_LDRSH_LT
+ arm_LDRSH_GT
+ arm_LDRSH_LE
+ arm_LDRSH
+ arm_LDRSH_ZZ
+ arm_LDRSHT_EQ
+ arm_LDRSHT_NE
+ arm_LDRSHT_CS
+ arm_LDRSHT_CC
+ arm_LDRSHT_MI
+ arm_LDRSHT_PL
+ arm_LDRSHT_VS
+ arm_LDRSHT_VC
+ arm_LDRSHT_HI
+ arm_LDRSHT_LS
+ arm_LDRSHT_GE
+ arm_LDRSHT_LT
+ arm_LDRSHT_GT
+ arm_LDRSHT_LE
+ arm_LDRSHT
+ arm_LDRSHT_ZZ
+ arm_LDRT_EQ
+ arm_LDRT_NE
+ arm_LDRT_CS
+ arm_LDRT_CC
+ arm_LDRT_MI
+ arm_LDRT_PL
+ arm_LDRT_VS
+ arm_LDRT_VC
+ arm_LDRT_HI
+ arm_LDRT_LS
+ arm_LDRT_GE
+ arm_LDRT_LT
+ arm_LDRT_GT
+ arm_LDRT_LE
+ arm_LDRT
+ arm_LDRT_ZZ
+ arm_LSL_EQ
+ arm_LSL_NE
+ arm_LSL_CS
+ arm_LSL_CC
+ arm_LSL_MI
+ arm_LSL_PL
+ arm_LSL_VS
+ arm_LSL_VC
+ arm_LSL_HI
+ arm_LSL_LS
+ arm_LSL_GE
+ arm_LSL_LT
+ arm_LSL_GT
+ arm_LSL_LE
+ arm_LSL
+ arm_LSL_ZZ
+ arm_LSL_S_EQ
+ arm_LSL_S_NE
+ arm_LSL_S_CS
+ arm_LSL_S_CC
+ arm_LSL_S_MI
+ arm_LSL_S_PL
+ arm_LSL_S_VS
+ arm_LSL_S_VC
+ arm_LSL_S_HI
+ arm_LSL_S_LS
+ arm_LSL_S_GE
+ arm_LSL_S_LT
+ arm_LSL_S_GT
+ arm_LSL_S_LE
+ arm_LSL_S
+ arm_LSL_S_ZZ
+ arm_LSR_EQ
+ arm_LSR_NE
+ arm_LSR_CS
+ arm_LSR_CC
+ arm_LSR_MI
+ arm_LSR_PL
+ arm_LSR_VS
+ arm_LSR_VC
+ arm_LSR_HI
+ arm_LSR_LS
+ arm_LSR_GE
+ arm_LSR_LT
+ arm_LSR_GT
+ arm_LSR_LE
+ arm_LSR
+ arm_LSR_ZZ
+ arm_LSR_S_EQ
+ arm_LSR_S_NE
+ arm_LSR_S_CS
+ arm_LSR_S_CC
+ arm_LSR_S_MI
+ arm_LSR_S_PL
+ arm_LSR_S_VS
+ arm_LSR_S_VC
+ arm_LSR_S_HI
+ arm_LSR_S_LS
+ arm_LSR_S_GE
+ arm_LSR_S_LT
+ arm_LSR_S_GT
+ arm_LSR_S_LE
+ arm_LSR_S
+ arm_LSR_S_ZZ
+ arm_MLA_EQ
+ arm_MLA_NE
+ arm_MLA_CS
+ arm_MLA_CC
+ arm_MLA_MI
+ arm_MLA_PL
+ arm_MLA_VS
+ arm_MLA_VC
+ arm_MLA_HI
+ arm_MLA_LS
+ arm_MLA_GE
+ arm_MLA_LT
+ arm_MLA_GT
+ arm_MLA_LE
+ arm_MLA
+ arm_MLA_ZZ
+ arm_MLA_S_EQ
+ arm_MLA_S_NE
+ arm_MLA_S_CS
+ arm_MLA_S_CC
+ arm_MLA_S_MI
+ arm_MLA_S_PL
+ arm_MLA_S_VS
+ arm_MLA_S_VC
+ arm_MLA_S_HI
+ arm_MLA_S_LS
+ arm_MLA_S_GE
+ arm_MLA_S_LT
+ arm_MLA_S_GT
+ arm_MLA_S_LE
+ arm_MLA_S
+ arm_MLA_S_ZZ
+ arm_MLS_EQ
+ arm_MLS_NE
+ arm_MLS_CS
+ arm_MLS_CC
+ arm_MLS_MI
+ arm_MLS_PL
+ arm_MLS_VS
+ arm_MLS_VC
+ arm_MLS_HI
+ arm_MLS_LS
+ arm_MLS_GE
+ arm_MLS_LT
+ arm_MLS_GT
+ arm_MLS_LE
+ arm_MLS
+ arm_MLS_ZZ
+ arm_MOV_EQ
+ arm_MOV_NE
+ arm_MOV_CS
+ arm_MOV_CC
+ arm_MOV_MI
+ arm_MOV_PL
+ arm_MOV_VS
+ arm_MOV_VC
+ arm_MOV_HI
+ arm_MOV_LS
+ arm_MOV_GE
+ arm_MOV_LT
+ arm_MOV_GT
+ arm_MOV_LE
+ arm_MOV
+ arm_MOV_ZZ
+ arm_MOV_S_EQ
+ arm_MOV_S_NE
+ arm_MOV_S_CS
+ arm_MOV_S_CC
+ arm_MOV_S_MI
+ arm_MOV_S_PL
+ arm_MOV_S_VS
+ arm_MOV_S_VC
+ arm_MOV_S_HI
+ arm_MOV_S_LS
+ arm_MOV_S_GE
+ arm_MOV_S_LT
+ arm_MOV_S_GT
+ arm_MOV_S_LE
+ arm_MOV_S
+ arm_MOV_S_ZZ
+ arm_MOVT_EQ
+ arm_MOVT_NE
+ arm_MOVT_CS
+ arm_MOVT_CC
+ arm_MOVT_MI
+ arm_MOVT_PL
+ arm_MOVT_VS
+ arm_MOVT_VC
+ arm_MOVT_HI
+ arm_MOVT_LS
+ arm_MOVT_GE
+ arm_MOVT_LT
+ arm_MOVT_GT
+ arm_MOVT_LE
+ arm_MOVT
+ arm_MOVT_ZZ
+ arm_MOVW_EQ
+ arm_MOVW_NE
+ arm_MOVW_CS
+ arm_MOVW_CC
+ arm_MOVW_MI
+ arm_MOVW_PL
+ arm_MOVW_VS
+ arm_MOVW_VC
+ arm_MOVW_HI
+ arm_MOVW_LS
+ arm_MOVW_GE
+ arm_MOVW_LT
+ arm_MOVW_GT
+ arm_MOVW_LE
+ arm_MOVW
+ arm_MOVW_ZZ
+ arm_MRS_EQ
+ arm_MRS_NE
+ arm_MRS_CS
+ arm_MRS_CC
+ arm_MRS_MI
+ arm_MRS_PL
+ arm_MRS_VS
+ arm_MRS_VC
+ arm_MRS_HI
+ arm_MRS_LS
+ arm_MRS_GE
+ arm_MRS_LT
+ arm_MRS_GT
+ arm_MRS_LE
+ arm_MRS
+ arm_MRS_ZZ
+ arm_MUL_EQ
+ arm_MUL_NE
+ arm_MUL_CS
+ arm_MUL_CC
+ arm_MUL_MI
+ arm_MUL_PL
+ arm_MUL_VS
+ arm_MUL_VC
+ arm_MUL_HI
+ arm_MUL_LS
+ arm_MUL_GE
+ arm_MUL_LT
+ arm_MUL_GT
+ arm_MUL_LE
+ arm_MUL
+ arm_MUL_ZZ
+ arm_MUL_S_EQ
+ arm_MUL_S_NE
+ arm_MUL_S_CS
+ arm_MUL_S_CC
+ arm_MUL_S_MI
+ arm_MUL_S_PL
+ arm_MUL_S_VS
+ arm_MUL_S_VC
+ arm_MUL_S_HI
+ arm_MUL_S_LS
+ arm_MUL_S_GE
+ arm_MUL_S_LT
+ arm_MUL_S_GT
+ arm_MUL_S_LE
+ arm_MUL_S
+ arm_MUL_S_ZZ
+ arm_MVN_EQ
+ arm_MVN_NE
+ arm_MVN_CS
+ arm_MVN_CC
+ arm_MVN_MI
+ arm_MVN_PL
+ arm_MVN_VS
+ arm_MVN_VC
+ arm_MVN_HI
+ arm_MVN_LS
+ arm_MVN_GE
+ arm_MVN_LT
+ arm_MVN_GT
+ arm_MVN_LE
+ arm_MVN
+ arm_MVN_ZZ
+ arm_MVN_S_EQ
+ arm_MVN_S_NE
+ arm_MVN_S_CS
+ arm_MVN_S_CC
+ arm_MVN_S_MI
+ arm_MVN_S_PL
+ arm_MVN_S_VS
+ arm_MVN_S_VC
+ arm_MVN_S_HI
+ arm_MVN_S_LS
+ arm_MVN_S_GE
+ arm_MVN_S_LT
+ arm_MVN_S_GT
+ arm_MVN_S_LE
+ arm_MVN_S
+ arm_MVN_S_ZZ
+ arm_NOP_EQ
+ arm_NOP_NE
+ arm_NOP_CS
+ arm_NOP_CC
+ arm_NOP_MI
+ arm_NOP_PL
+ arm_NOP_VS
+ arm_NOP_VC
+ arm_NOP_HI
+ arm_NOP_LS
+ arm_NOP_GE
+ arm_NOP_LT
+ arm_NOP_GT
+ arm_NOP_LE
+ arm_NOP
+ arm_NOP_ZZ
+ arm_ORR_EQ
+ arm_ORR_NE
+ arm_ORR_CS
+ arm_ORR_CC
+ arm_ORR_MI
+ arm_ORR_PL
+ arm_ORR_VS
+ arm_ORR_VC
+ arm_ORR_HI
+ arm_ORR_LS
+ arm_ORR_GE
+ arm_ORR_LT
+ arm_ORR_GT
+ arm_ORR_LE
+ arm_ORR
+ arm_ORR_ZZ
+ arm_ORR_S_EQ
+ arm_ORR_S_NE
+ arm_ORR_S_CS
+ arm_ORR_S_CC
+ arm_ORR_S_MI
+ arm_ORR_S_PL
+ arm_ORR_S_VS
+ arm_ORR_S_VC
+ arm_ORR_S_HI
+ arm_ORR_S_LS
+ arm_ORR_S_GE
+ arm_ORR_S_LT
+ arm_ORR_S_GT
+ arm_ORR_S_LE
+ arm_ORR_S
+ arm_ORR_S_ZZ
+ arm_PKHBT_EQ
+ arm_PKHBT_NE
+ arm_PKHBT_CS
+ arm_PKHBT_CC
+ arm_PKHBT_MI
+ arm_PKHBT_PL
+ arm_PKHBT_VS
+ arm_PKHBT_VC
+ arm_PKHBT_HI
+ arm_PKHBT_LS
+ arm_PKHBT_GE
+ arm_PKHBT_LT
+ arm_PKHBT_GT
+ arm_PKHBT_LE
+ arm_PKHBT
+ arm_PKHBT_ZZ
+ arm_PKHTB_EQ
+ arm_PKHTB_NE
+ arm_PKHTB_CS
+ arm_PKHTB_CC
+ arm_PKHTB_MI
+ arm_PKHTB_PL
+ arm_PKHTB_VS
+ arm_PKHTB_VC
+ arm_PKHTB_HI
+ arm_PKHTB_LS
+ arm_PKHTB_GE
+ arm_PKHTB_LT
+ arm_PKHTB_GT
+ arm_PKHTB_LE
+ arm_PKHTB
+ arm_PKHTB_ZZ
+ arm_PLD_W
+ arm_PLD
+ arm_PLI
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_POP_EQ
+ arm_POP_NE
+ arm_POP_CS
+ arm_POP_CC
+ arm_POP_MI
+ arm_POP_PL
+ arm_POP_VS
+ arm_POP_VC
+ arm_POP_HI
+ arm_POP_LS
+ arm_POP_GE
+ arm_POP_LT
+ arm_POP_GT
+ arm_POP_LE
+ arm_POP
+ arm_POP_ZZ
+ arm_PUSH_EQ
+ arm_PUSH_NE
+ arm_PUSH_CS
+ arm_PUSH_CC
+ arm_PUSH_MI
+ arm_PUSH_PL
+ arm_PUSH_VS
+ arm_PUSH_VC
+ arm_PUSH_HI
+ arm_PUSH_LS
+ arm_PUSH_GE
+ arm_PUSH_LT
+ arm_PUSH_GT
+ arm_PUSH_LE
+ arm_PUSH
+ arm_PUSH_ZZ
+ arm_QADD_EQ
+ arm_QADD_NE
+ arm_QADD_CS
+ arm_QADD_CC
+ arm_QADD_MI
+ arm_QADD_PL
+ arm_QADD_VS
+ arm_QADD_VC
+ arm_QADD_HI
+ arm_QADD_LS
+ arm_QADD_GE
+ arm_QADD_LT
+ arm_QADD_GT
+ arm_QADD_LE
+ arm_QADD
+ arm_QADD_ZZ
+ arm_QADD16_EQ
+ arm_QADD16_NE
+ arm_QADD16_CS
+ arm_QADD16_CC
+ arm_QADD16_MI
+ arm_QADD16_PL
+ arm_QADD16_VS
+ arm_QADD16_VC
+ arm_QADD16_HI
+ arm_QADD16_LS
+ arm_QADD16_GE
+ arm_QADD16_LT
+ arm_QADD16_GT
+ arm_QADD16_LE
+ arm_QADD16
+ arm_QADD16_ZZ
+ arm_QADD8_EQ
+ arm_QADD8_NE
+ arm_QADD8_CS
+ arm_QADD8_CC
+ arm_QADD8_MI
+ arm_QADD8_PL
+ arm_QADD8_VS
+ arm_QADD8_VC
+ arm_QADD8_HI
+ arm_QADD8_LS
+ arm_QADD8_GE
+ arm_QADD8_LT
+ arm_QADD8_GT
+ arm_QADD8_LE
+ arm_QADD8
+ arm_QADD8_ZZ
+ arm_QASX_EQ
+ arm_QASX_NE
+ arm_QASX_CS
+ arm_QASX_CC
+ arm_QASX_MI
+ arm_QASX_PL
+ arm_QASX_VS
+ arm_QASX_VC
+ arm_QASX_HI
+ arm_QASX_LS
+ arm_QASX_GE
+ arm_QASX_LT
+ arm_QASX_GT
+ arm_QASX_LE
+ arm_QASX
+ arm_QASX_ZZ
+ arm_QDADD_EQ
+ arm_QDADD_NE
+ arm_QDADD_CS
+ arm_QDADD_CC
+ arm_QDADD_MI
+ arm_QDADD_PL
+ arm_QDADD_VS
+ arm_QDADD_VC
+ arm_QDADD_HI
+ arm_QDADD_LS
+ arm_QDADD_GE
+ arm_QDADD_LT
+ arm_QDADD_GT
+ arm_QDADD_LE
+ arm_QDADD
+ arm_QDADD_ZZ
+ arm_QDSUB_EQ
+ arm_QDSUB_NE
+ arm_QDSUB_CS
+ arm_QDSUB_CC
+ arm_QDSUB_MI
+ arm_QDSUB_PL
+ arm_QDSUB_VS
+ arm_QDSUB_VC
+ arm_QDSUB_HI
+ arm_QDSUB_LS
+ arm_QDSUB_GE
+ arm_QDSUB_LT
+ arm_QDSUB_GT
+ arm_QDSUB_LE
+ arm_QDSUB
+ arm_QDSUB_ZZ
+ arm_QSAX_EQ
+ arm_QSAX_NE
+ arm_QSAX_CS
+ arm_QSAX_CC
+ arm_QSAX_MI
+ arm_QSAX_PL
+ arm_QSAX_VS
+ arm_QSAX_VC
+ arm_QSAX_HI
+ arm_QSAX_LS
+ arm_QSAX_GE
+ arm_QSAX_LT
+ arm_QSAX_GT
+ arm_QSAX_LE
+ arm_QSAX
+ arm_QSAX_ZZ
+ arm_QSUB_EQ
+ arm_QSUB_NE
+ arm_QSUB_CS
+ arm_QSUB_CC
+ arm_QSUB_MI
+ arm_QSUB_PL
+ arm_QSUB_VS
+ arm_QSUB_VC
+ arm_QSUB_HI
+ arm_QSUB_LS
+ arm_QSUB_GE
+ arm_QSUB_LT
+ arm_QSUB_GT
+ arm_QSUB_LE
+ arm_QSUB
+ arm_QSUB_ZZ
+ arm_QSUB16_EQ
+ arm_QSUB16_NE
+ arm_QSUB16_CS
+ arm_QSUB16_CC
+ arm_QSUB16_MI
+ arm_QSUB16_PL
+ arm_QSUB16_VS
+ arm_QSUB16_VC
+ arm_QSUB16_HI
+ arm_QSUB16_LS
+ arm_QSUB16_GE
+ arm_QSUB16_LT
+ arm_QSUB16_GT
+ arm_QSUB16_LE
+ arm_QSUB16
+ arm_QSUB16_ZZ
+ arm_QSUB8_EQ
+ arm_QSUB8_NE
+ arm_QSUB8_CS
+ arm_QSUB8_CC
+ arm_QSUB8_MI
+ arm_QSUB8_PL
+ arm_QSUB8_VS
+ arm_QSUB8_VC
+ arm_QSUB8_HI
+ arm_QSUB8_LS
+ arm_QSUB8_GE
+ arm_QSUB8_LT
+ arm_QSUB8_GT
+ arm_QSUB8_LE
+ arm_QSUB8
+ arm_QSUB8_ZZ
+ arm_RBIT_EQ
+ arm_RBIT_NE
+ arm_RBIT_CS
+ arm_RBIT_CC
+ arm_RBIT_MI
+ arm_RBIT_PL
+ arm_RBIT_VS
+ arm_RBIT_VC
+ arm_RBIT_HI
+ arm_RBIT_LS
+ arm_RBIT_GE
+ arm_RBIT_LT
+ arm_RBIT_GT
+ arm_RBIT_LE
+ arm_RBIT
+ arm_RBIT_ZZ
+ arm_REV_EQ
+ arm_REV_NE
+ arm_REV_CS
+ arm_REV_CC
+ arm_REV_MI
+ arm_REV_PL
+ arm_REV_VS
+ arm_REV_VC
+ arm_REV_HI
+ arm_REV_LS
+ arm_REV_GE
+ arm_REV_LT
+ arm_REV_GT
+ arm_REV_LE
+ arm_REV
+ arm_REV_ZZ
+ arm_REV16_EQ
+ arm_REV16_NE
+ arm_REV16_CS
+ arm_REV16_CC
+ arm_REV16_MI
+ arm_REV16_PL
+ arm_REV16_VS
+ arm_REV16_VC
+ arm_REV16_HI
+ arm_REV16_LS
+ arm_REV16_GE
+ arm_REV16_LT
+ arm_REV16_GT
+ arm_REV16_LE
+ arm_REV16
+ arm_REV16_ZZ
+ arm_REVSH_EQ
+ arm_REVSH_NE
+ arm_REVSH_CS
+ arm_REVSH_CC
+ arm_REVSH_MI
+ arm_REVSH_PL
+ arm_REVSH_VS
+ arm_REVSH_VC
+ arm_REVSH_HI
+ arm_REVSH_LS
+ arm_REVSH_GE
+ arm_REVSH_LT
+ arm_REVSH_GT
+ arm_REVSH_LE
+ arm_REVSH
+ arm_REVSH_ZZ
+ arm_ROR_EQ
+ arm_ROR_NE
+ arm_ROR_CS
+ arm_ROR_CC
+ arm_ROR_MI
+ arm_ROR_PL
+ arm_ROR_VS
+ arm_ROR_VC
+ arm_ROR_HI
+ arm_ROR_LS
+ arm_ROR_GE
+ arm_ROR_LT
+ arm_ROR_GT
+ arm_ROR_LE
+ arm_ROR
+ arm_ROR_ZZ
+ arm_ROR_S_EQ
+ arm_ROR_S_NE
+ arm_ROR_S_CS
+ arm_ROR_S_CC
+ arm_ROR_S_MI
+ arm_ROR_S_PL
+ arm_ROR_S_VS
+ arm_ROR_S_VC
+ arm_ROR_S_HI
+ arm_ROR_S_LS
+ arm_ROR_S_GE
+ arm_ROR_S_LT
+ arm_ROR_S_GT
+ arm_ROR_S_LE
+ arm_ROR_S
+ arm_ROR_S_ZZ
+ arm_RRX_EQ
+ arm_RRX_NE
+ arm_RRX_CS
+ arm_RRX_CC
+ arm_RRX_MI
+ arm_RRX_PL
+ arm_RRX_VS
+ arm_RRX_VC
+ arm_RRX_HI
+ arm_RRX_LS
+ arm_RRX_GE
+ arm_RRX_LT
+ arm_RRX_GT
+ arm_RRX_LE
+ arm_RRX
+ arm_RRX_ZZ
+ arm_RRX_S_EQ
+ arm_RRX_S_NE
+ arm_RRX_S_CS
+ arm_RRX_S_CC
+ arm_RRX_S_MI
+ arm_RRX_S_PL
+ arm_RRX_S_VS
+ arm_RRX_S_VC
+ arm_RRX_S_HI
+ arm_RRX_S_LS
+ arm_RRX_S_GE
+ arm_RRX_S_LT
+ arm_RRX_S_GT
+ arm_RRX_S_LE
+ arm_RRX_S
+ arm_RRX_S_ZZ
+ arm_RSB_EQ
+ arm_RSB_NE
+ arm_RSB_CS
+ arm_RSB_CC
+ arm_RSB_MI
+ arm_RSB_PL
+ arm_RSB_VS
+ arm_RSB_VC
+ arm_RSB_HI
+ arm_RSB_LS
+ arm_RSB_GE
+ arm_RSB_LT
+ arm_RSB_GT
+ arm_RSB_LE
+ arm_RSB
+ arm_RSB_ZZ
+ arm_RSB_S_EQ
+ arm_RSB_S_NE
+ arm_RSB_S_CS
+ arm_RSB_S_CC
+ arm_RSB_S_MI
+ arm_RSB_S_PL
+ arm_RSB_S_VS
+ arm_RSB_S_VC
+ arm_RSB_S_HI
+ arm_RSB_S_LS
+ arm_RSB_S_GE
+ arm_RSB_S_LT
+ arm_RSB_S_GT
+ arm_RSB_S_LE
+ arm_RSB_S
+ arm_RSB_S_ZZ
+ arm_RSC_EQ
+ arm_RSC_NE
+ arm_RSC_CS
+ arm_RSC_CC
+ arm_RSC_MI
+ arm_RSC_PL
+ arm_RSC_VS
+ arm_RSC_VC
+ arm_RSC_HI
+ arm_RSC_LS
+ arm_RSC_GE
+ arm_RSC_LT
+ arm_RSC_GT
+ arm_RSC_LE
+ arm_RSC
+ arm_RSC_ZZ
+ arm_RSC_S_EQ
+ arm_RSC_S_NE
+ arm_RSC_S_CS
+ arm_RSC_S_CC
+ arm_RSC_S_MI
+ arm_RSC_S_PL
+ arm_RSC_S_VS
+ arm_RSC_S_VC
+ arm_RSC_S_HI
+ arm_RSC_S_LS
+ arm_RSC_S_GE
+ arm_RSC_S_LT
+ arm_RSC_S_GT
+ arm_RSC_S_LE
+ arm_RSC_S
+ arm_RSC_S_ZZ
+ arm_SADD16_EQ
+ arm_SADD16_NE
+ arm_SADD16_CS
+ arm_SADD16_CC
+ arm_SADD16_MI
+ arm_SADD16_PL
+ arm_SADD16_VS
+ arm_SADD16_VC
+ arm_SADD16_HI
+ arm_SADD16_LS
+ arm_SADD16_GE
+ arm_SADD16_LT
+ arm_SADD16_GT
+ arm_SADD16_LE
+ arm_SADD16
+ arm_SADD16_ZZ
+ arm_SADD8_EQ
+ arm_SADD8_NE
+ arm_SADD8_CS
+ arm_SADD8_CC
+ arm_SADD8_MI
+ arm_SADD8_PL
+ arm_SADD8_VS
+ arm_SADD8_VC
+ arm_SADD8_HI
+ arm_SADD8_LS
+ arm_SADD8_GE
+ arm_SADD8_LT
+ arm_SADD8_GT
+ arm_SADD8_LE
+ arm_SADD8
+ arm_SADD8_ZZ
+ arm_SASX_EQ
+ arm_SASX_NE
+ arm_SASX_CS
+ arm_SASX_CC
+ arm_SASX_MI
+ arm_SASX_PL
+ arm_SASX_VS
+ arm_SASX_VC
+ arm_SASX_HI
+ arm_SASX_LS
+ arm_SASX_GE
+ arm_SASX_LT
+ arm_SASX_GT
+ arm_SASX_LE
+ arm_SASX
+ arm_SASX_ZZ
+ arm_SBC_EQ
+ arm_SBC_NE
+ arm_SBC_CS
+ arm_SBC_CC
+ arm_SBC_MI
+ arm_SBC_PL
+ arm_SBC_VS
+ arm_SBC_VC
+ arm_SBC_HI
+ arm_SBC_LS
+ arm_SBC_GE
+ arm_SBC_LT
+ arm_SBC_GT
+ arm_SBC_LE
+ arm_SBC
+ arm_SBC_ZZ
+ arm_SBC_S_EQ
+ arm_SBC_S_NE
+ arm_SBC_S_CS
+ arm_SBC_S_CC
+ arm_SBC_S_MI
+ arm_SBC_S_PL
+ arm_SBC_S_VS
+ arm_SBC_S_VC
+ arm_SBC_S_HI
+ arm_SBC_S_LS
+ arm_SBC_S_GE
+ arm_SBC_S_LT
+ arm_SBC_S_GT
+ arm_SBC_S_LE
+ arm_SBC_S
+ arm_SBC_S_ZZ
+ arm_SBFX_EQ
+ arm_SBFX_NE
+ arm_SBFX_CS
+ arm_SBFX_CC
+ arm_SBFX_MI
+ arm_SBFX_PL
+ arm_SBFX_VS
+ arm_SBFX_VC
+ arm_SBFX_HI
+ arm_SBFX_LS
+ arm_SBFX_GE
+ arm_SBFX_LT
+ arm_SBFX_GT
+ arm_SBFX_LE
+ arm_SBFX
+ arm_SBFX_ZZ
+ arm_SEL_EQ
+ arm_SEL_NE
+ arm_SEL_CS
+ arm_SEL_CC
+ arm_SEL_MI
+ arm_SEL_PL
+ arm_SEL_VS
+ arm_SEL_VC
+ arm_SEL_HI
+ arm_SEL_LS
+ arm_SEL_GE
+ arm_SEL_LT
+ arm_SEL_GT
+ arm_SEL_LE
+ arm_SEL
+ arm_SEL_ZZ
+ arm_SETEND
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_SEV_EQ
+ arm_SEV_NE
+ arm_SEV_CS
+ arm_SEV_CC
+ arm_SEV_MI
+ arm_SEV_PL
+ arm_SEV_VS
+ arm_SEV_VC
+ arm_SEV_HI
+ arm_SEV_LS
+ arm_SEV_GE
+ arm_SEV_LT
+ arm_SEV_GT
+ arm_SEV_LE
+ arm_SEV
+ arm_SEV_ZZ
+ arm_SHADD16_EQ
+ arm_SHADD16_NE
+ arm_SHADD16_CS
+ arm_SHADD16_CC
+ arm_SHADD16_MI
+ arm_SHADD16_PL
+ arm_SHADD16_VS
+ arm_SHADD16_VC
+ arm_SHADD16_HI
+ arm_SHADD16_LS
+ arm_SHADD16_GE
+ arm_SHADD16_LT
+ arm_SHADD16_GT
+ arm_SHADD16_LE
+ arm_SHADD16
+ arm_SHADD16_ZZ
+ arm_SHADD8_EQ
+ arm_SHADD8_NE
+ arm_SHADD8_CS
+ arm_SHADD8_CC
+ arm_SHADD8_MI
+ arm_SHADD8_PL
+ arm_SHADD8_VS
+ arm_SHADD8_VC
+ arm_SHADD8_HI
+ arm_SHADD8_LS
+ arm_SHADD8_GE
+ arm_SHADD8_LT
+ arm_SHADD8_GT
+ arm_SHADD8_LE
+ arm_SHADD8
+ arm_SHADD8_ZZ
+ arm_SHASX_EQ
+ arm_SHASX_NE
+ arm_SHASX_CS
+ arm_SHASX_CC
+ arm_SHASX_MI
+ arm_SHASX_PL
+ arm_SHASX_VS
+ arm_SHASX_VC
+ arm_SHASX_HI
+ arm_SHASX_LS
+ arm_SHASX_GE
+ arm_SHASX_LT
+ arm_SHASX_GT
+ arm_SHASX_LE
+ arm_SHASX
+ arm_SHASX_ZZ
+ arm_SHSAX_EQ
+ arm_SHSAX_NE
+ arm_SHSAX_CS
+ arm_SHSAX_CC
+ arm_SHSAX_MI
+ arm_SHSAX_PL
+ arm_SHSAX_VS
+ arm_SHSAX_VC
+ arm_SHSAX_HI
+ arm_SHSAX_LS
+ arm_SHSAX_GE
+ arm_SHSAX_LT
+ arm_SHSAX_GT
+ arm_SHSAX_LE
+ arm_SHSAX
+ arm_SHSAX_ZZ
+ arm_SHSUB16_EQ
+ arm_SHSUB16_NE
+ arm_SHSUB16_CS
+ arm_SHSUB16_CC
+ arm_SHSUB16_MI
+ arm_SHSUB16_PL
+ arm_SHSUB16_VS
+ arm_SHSUB16_VC
+ arm_SHSUB16_HI
+ arm_SHSUB16_LS
+ arm_SHSUB16_GE
+ arm_SHSUB16_LT
+ arm_SHSUB16_GT
+ arm_SHSUB16_LE
+ arm_SHSUB16
+ arm_SHSUB16_ZZ
+ arm_SHSUB8_EQ
+ arm_SHSUB8_NE
+ arm_SHSUB8_CS
+ arm_SHSUB8_CC
+ arm_SHSUB8_MI
+ arm_SHSUB8_PL
+ arm_SHSUB8_VS
+ arm_SHSUB8_VC
+ arm_SHSUB8_HI
+ arm_SHSUB8_LS
+ arm_SHSUB8_GE
+ arm_SHSUB8_LT
+ arm_SHSUB8_GT
+ arm_SHSUB8_LE
+ arm_SHSUB8
+ arm_SHSUB8_ZZ
+ arm_SMLABB_EQ
+ arm_SMLABB_NE
+ arm_SMLABB_CS
+ arm_SMLABB_CC
+ arm_SMLABB_MI
+ arm_SMLABB_PL
+ arm_SMLABB_VS
+ arm_SMLABB_VC
+ arm_SMLABB_HI
+ arm_SMLABB_LS
+ arm_SMLABB_GE
+ arm_SMLABB_LT
+ arm_SMLABB_GT
+ arm_SMLABB_LE
+ arm_SMLABB
+ arm_SMLABB_ZZ
+ arm_SMLABT_EQ
+ arm_SMLABT_NE
+ arm_SMLABT_CS
+ arm_SMLABT_CC
+ arm_SMLABT_MI
+ arm_SMLABT_PL
+ arm_SMLABT_VS
+ arm_SMLABT_VC
+ arm_SMLABT_HI
+ arm_SMLABT_LS
+ arm_SMLABT_GE
+ arm_SMLABT_LT
+ arm_SMLABT_GT
+ arm_SMLABT_LE
+ arm_SMLABT
+ arm_SMLABT_ZZ
+ arm_SMLATB_EQ
+ arm_SMLATB_NE
+ arm_SMLATB_CS
+ arm_SMLATB_CC
+ arm_SMLATB_MI
+ arm_SMLATB_PL
+ arm_SMLATB_VS
+ arm_SMLATB_VC
+ arm_SMLATB_HI
+ arm_SMLATB_LS
+ arm_SMLATB_GE
+ arm_SMLATB_LT
+ arm_SMLATB_GT
+ arm_SMLATB_LE
+ arm_SMLATB
+ arm_SMLATB_ZZ
+ arm_SMLATT_EQ
+ arm_SMLATT_NE
+ arm_SMLATT_CS
+ arm_SMLATT_CC
+ arm_SMLATT_MI
+ arm_SMLATT_PL
+ arm_SMLATT_VS
+ arm_SMLATT_VC
+ arm_SMLATT_HI
+ arm_SMLATT_LS
+ arm_SMLATT_GE
+ arm_SMLATT_LT
+ arm_SMLATT_GT
+ arm_SMLATT_LE
+ arm_SMLATT
+ arm_SMLATT_ZZ
+ arm_SMLAD_EQ
+ arm_SMLAD_NE
+ arm_SMLAD_CS
+ arm_SMLAD_CC
+ arm_SMLAD_MI
+ arm_SMLAD_PL
+ arm_SMLAD_VS
+ arm_SMLAD_VC
+ arm_SMLAD_HI
+ arm_SMLAD_LS
+ arm_SMLAD_GE
+ arm_SMLAD_LT
+ arm_SMLAD_GT
+ arm_SMLAD_LE
+ arm_SMLAD
+ arm_SMLAD_ZZ
+ arm_SMLAD_X_EQ
+ arm_SMLAD_X_NE
+ arm_SMLAD_X_CS
+ arm_SMLAD_X_CC
+ arm_SMLAD_X_MI
+ arm_SMLAD_X_PL
+ arm_SMLAD_X_VS
+ arm_SMLAD_X_VC
+ arm_SMLAD_X_HI
+ arm_SMLAD_X_LS
+ arm_SMLAD_X_GE
+ arm_SMLAD_X_LT
+ arm_SMLAD_X_GT
+ arm_SMLAD_X_LE
+ arm_SMLAD_X
+ arm_SMLAD_X_ZZ
+ arm_SMLAL_EQ
+ arm_SMLAL_NE
+ arm_SMLAL_CS
+ arm_SMLAL_CC
+ arm_SMLAL_MI
+ arm_SMLAL_PL
+ arm_SMLAL_VS
+ arm_SMLAL_VC
+ arm_SMLAL_HI
+ arm_SMLAL_LS
+ arm_SMLAL_GE
+ arm_SMLAL_LT
+ arm_SMLAL_GT
+ arm_SMLAL_LE
+ arm_SMLAL
+ arm_SMLAL_ZZ
+ arm_SMLAL_S_EQ
+ arm_SMLAL_S_NE
+ arm_SMLAL_S_CS
+ arm_SMLAL_S_CC
+ arm_SMLAL_S_MI
+ arm_SMLAL_S_PL
+ arm_SMLAL_S_VS
+ arm_SMLAL_S_VC
+ arm_SMLAL_S_HI
+ arm_SMLAL_S_LS
+ arm_SMLAL_S_GE
+ arm_SMLAL_S_LT
+ arm_SMLAL_S_GT
+ arm_SMLAL_S_LE
+ arm_SMLAL_S
+ arm_SMLAL_S_ZZ
+ arm_SMLALBB_EQ
+ arm_SMLALBB_NE
+ arm_SMLALBB_CS
+ arm_SMLALBB_CC
+ arm_SMLALBB_MI
+ arm_SMLALBB_PL
+ arm_SMLALBB_VS
+ arm_SMLALBB_VC
+ arm_SMLALBB_HI
+ arm_SMLALBB_LS
+ arm_SMLALBB_GE
+ arm_SMLALBB_LT
+ arm_SMLALBB_GT
+ arm_SMLALBB_LE
+ arm_SMLALBB
+ arm_SMLALBB_ZZ
+ arm_SMLALBT_EQ
+ arm_SMLALBT_NE
+ arm_SMLALBT_CS
+ arm_SMLALBT_CC
+ arm_SMLALBT_MI
+ arm_SMLALBT_PL
+ arm_SMLALBT_VS
+ arm_SMLALBT_VC
+ arm_SMLALBT_HI
+ arm_SMLALBT_LS
+ arm_SMLALBT_GE
+ arm_SMLALBT_LT
+ arm_SMLALBT_GT
+ arm_SMLALBT_LE
+ arm_SMLALBT
+ arm_SMLALBT_ZZ
+ arm_SMLALTB_EQ
+ arm_SMLALTB_NE
+ arm_SMLALTB_CS
+ arm_SMLALTB_CC
+ arm_SMLALTB_MI
+ arm_SMLALTB_PL
+ arm_SMLALTB_VS
+ arm_SMLALTB_VC
+ arm_SMLALTB_HI
+ arm_SMLALTB_LS
+ arm_SMLALTB_GE
+ arm_SMLALTB_LT
+ arm_SMLALTB_GT
+ arm_SMLALTB_LE
+ arm_SMLALTB
+ arm_SMLALTB_ZZ
+ arm_SMLALTT_EQ
+ arm_SMLALTT_NE
+ arm_SMLALTT_CS
+ arm_SMLALTT_CC
+ arm_SMLALTT_MI
+ arm_SMLALTT_PL
+ arm_SMLALTT_VS
+ arm_SMLALTT_VC
+ arm_SMLALTT_HI
+ arm_SMLALTT_LS
+ arm_SMLALTT_GE
+ arm_SMLALTT_LT
+ arm_SMLALTT_GT
+ arm_SMLALTT_LE
+ arm_SMLALTT
+ arm_SMLALTT_ZZ
+ arm_SMLALD_EQ
+ arm_SMLALD_NE
+ arm_SMLALD_CS
+ arm_SMLALD_CC
+ arm_SMLALD_MI
+ arm_SMLALD_PL
+ arm_SMLALD_VS
+ arm_SMLALD_VC
+ arm_SMLALD_HI
+ arm_SMLALD_LS
+ arm_SMLALD_GE
+ arm_SMLALD_LT
+ arm_SMLALD_GT
+ arm_SMLALD_LE
+ arm_SMLALD
+ arm_SMLALD_ZZ
+ arm_SMLALD_X_EQ
+ arm_SMLALD_X_NE
+ arm_SMLALD_X_CS
+ arm_SMLALD_X_CC
+ arm_SMLALD_X_MI
+ arm_SMLALD_X_PL
+ arm_SMLALD_X_VS
+ arm_SMLALD_X_VC
+ arm_SMLALD_X_HI
+ arm_SMLALD_X_LS
+ arm_SMLALD_X_GE
+ arm_SMLALD_X_LT
+ arm_SMLALD_X_GT
+ arm_SMLALD_X_LE
+ arm_SMLALD_X
+ arm_SMLALD_X_ZZ
+ arm_SMLAWB_EQ
+ arm_SMLAWB_NE
+ arm_SMLAWB_CS
+ arm_SMLAWB_CC
+ arm_SMLAWB_MI
+ arm_SMLAWB_PL
+ arm_SMLAWB_VS
+ arm_SMLAWB_VC
+ arm_SMLAWB_HI
+ arm_SMLAWB_LS
+ arm_SMLAWB_GE
+ arm_SMLAWB_LT
+ arm_SMLAWB_GT
+ arm_SMLAWB_LE
+ arm_SMLAWB
+ arm_SMLAWB_ZZ
+ arm_SMLAWT_EQ
+ arm_SMLAWT_NE
+ arm_SMLAWT_CS
+ arm_SMLAWT_CC
+ arm_SMLAWT_MI
+ arm_SMLAWT_PL
+ arm_SMLAWT_VS
+ arm_SMLAWT_VC
+ arm_SMLAWT_HI
+ arm_SMLAWT_LS
+ arm_SMLAWT_GE
+ arm_SMLAWT_LT
+ arm_SMLAWT_GT
+ arm_SMLAWT_LE
+ arm_SMLAWT
+ arm_SMLAWT_ZZ
+ arm_SMLSD_EQ
+ arm_SMLSD_NE
+ arm_SMLSD_CS
+ arm_SMLSD_CC
+ arm_SMLSD_MI
+ arm_SMLSD_PL
+ arm_SMLSD_VS
+ arm_SMLSD_VC
+ arm_SMLSD_HI
+ arm_SMLSD_LS
+ arm_SMLSD_GE
+ arm_SMLSD_LT
+ arm_SMLSD_GT
+ arm_SMLSD_LE
+ arm_SMLSD
+ arm_SMLSD_ZZ
+ arm_SMLSD_X_EQ
+ arm_SMLSD_X_NE
+ arm_SMLSD_X_CS
+ arm_SMLSD_X_CC
+ arm_SMLSD_X_MI
+ arm_SMLSD_X_PL
+ arm_SMLSD_X_VS
+ arm_SMLSD_X_VC
+ arm_SMLSD_X_HI
+ arm_SMLSD_X_LS
+ arm_SMLSD_X_GE
+ arm_SMLSD_X_LT
+ arm_SMLSD_X_GT
+ arm_SMLSD_X_LE
+ arm_SMLSD_X
+ arm_SMLSD_X_ZZ
+ arm_SMLSLD_EQ
+ arm_SMLSLD_NE
+ arm_SMLSLD_CS
+ arm_SMLSLD_CC
+ arm_SMLSLD_MI
+ arm_SMLSLD_PL
+ arm_SMLSLD_VS
+ arm_SMLSLD_VC
+ arm_SMLSLD_HI
+ arm_SMLSLD_LS
+ arm_SMLSLD_GE
+ arm_SMLSLD_LT
+ arm_SMLSLD_GT
+ arm_SMLSLD_LE
+ arm_SMLSLD
+ arm_SMLSLD_ZZ
+ arm_SMLSLD_X_EQ
+ arm_SMLSLD_X_NE
+ arm_SMLSLD_X_CS
+ arm_SMLSLD_X_CC
+ arm_SMLSLD_X_MI
+ arm_SMLSLD_X_PL
+ arm_SMLSLD_X_VS
+ arm_SMLSLD_X_VC
+ arm_SMLSLD_X_HI
+ arm_SMLSLD_X_LS
+ arm_SMLSLD_X_GE
+ arm_SMLSLD_X_LT
+ arm_SMLSLD_X_GT
+ arm_SMLSLD_X_LE
+ arm_SMLSLD_X
+ arm_SMLSLD_X_ZZ
+ arm_SMMLA_EQ
+ arm_SMMLA_NE
+ arm_SMMLA_CS
+ arm_SMMLA_CC
+ arm_SMMLA_MI
+ arm_SMMLA_PL
+ arm_SMMLA_VS
+ arm_SMMLA_VC
+ arm_SMMLA_HI
+ arm_SMMLA_LS
+ arm_SMMLA_GE
+ arm_SMMLA_LT
+ arm_SMMLA_GT
+ arm_SMMLA_LE
+ arm_SMMLA
+ arm_SMMLA_ZZ
+ arm_SMMLA_R_EQ
+ arm_SMMLA_R_NE
+ arm_SMMLA_R_CS
+ arm_SMMLA_R_CC
+ arm_SMMLA_R_MI
+ arm_SMMLA_R_PL
+ arm_SMMLA_R_VS
+ arm_SMMLA_R_VC
+ arm_SMMLA_R_HI
+ arm_SMMLA_R_LS
+ arm_SMMLA_R_GE
+ arm_SMMLA_R_LT
+ arm_SMMLA_R_GT
+ arm_SMMLA_R_LE
+ arm_SMMLA_R
+ arm_SMMLA_R_ZZ
+ arm_SMMLS_EQ
+ arm_SMMLS_NE
+ arm_SMMLS_CS
+ arm_SMMLS_CC
+ arm_SMMLS_MI
+ arm_SMMLS_PL
+ arm_SMMLS_VS
+ arm_SMMLS_VC
+ arm_SMMLS_HI
+ arm_SMMLS_LS
+ arm_SMMLS_GE
+ arm_SMMLS_LT
+ arm_SMMLS_GT
+ arm_SMMLS_LE
+ arm_SMMLS
+ arm_SMMLS_ZZ
+ arm_SMMLS_R_EQ
+ arm_SMMLS_R_NE
+ arm_SMMLS_R_CS
+ arm_SMMLS_R_CC
+ arm_SMMLS_R_MI
+ arm_SMMLS_R_PL
+ arm_SMMLS_R_VS
+ arm_SMMLS_R_VC
+ arm_SMMLS_R_HI
+ arm_SMMLS_R_LS
+ arm_SMMLS_R_GE
+ arm_SMMLS_R_LT
+ arm_SMMLS_R_GT
+ arm_SMMLS_R_LE
+ arm_SMMLS_R
+ arm_SMMLS_R_ZZ
+ arm_SMMUL_EQ
+ arm_SMMUL_NE
+ arm_SMMUL_CS
+ arm_SMMUL_CC
+ arm_SMMUL_MI
+ arm_SMMUL_PL
+ arm_SMMUL_VS
+ arm_SMMUL_VC
+ arm_SMMUL_HI
+ arm_SMMUL_LS
+ arm_SMMUL_GE
+ arm_SMMUL_LT
+ arm_SMMUL_GT
+ arm_SMMUL_LE
+ arm_SMMUL
+ arm_SMMUL_ZZ
+ arm_SMMUL_R_EQ
+ arm_SMMUL_R_NE
+ arm_SMMUL_R_CS
+ arm_SMMUL_R_CC
+ arm_SMMUL_R_MI
+ arm_SMMUL_R_PL
+ arm_SMMUL_R_VS
+ arm_SMMUL_R_VC
+ arm_SMMUL_R_HI
+ arm_SMMUL_R_LS
+ arm_SMMUL_R_GE
+ arm_SMMUL_R_LT
+ arm_SMMUL_R_GT
+ arm_SMMUL_R_LE
+ arm_SMMUL_R
+ arm_SMMUL_R_ZZ
+ arm_SMUAD_EQ
+ arm_SMUAD_NE
+ arm_SMUAD_CS
+ arm_SMUAD_CC
+ arm_SMUAD_MI
+ arm_SMUAD_PL
+ arm_SMUAD_VS
+ arm_SMUAD_VC
+ arm_SMUAD_HI
+ arm_SMUAD_LS
+ arm_SMUAD_GE
+ arm_SMUAD_LT
+ arm_SMUAD_GT
+ arm_SMUAD_LE
+ arm_SMUAD
+ arm_SMUAD_ZZ
+ arm_SMUAD_X_EQ
+ arm_SMUAD_X_NE
+ arm_SMUAD_X_CS
+ arm_SMUAD_X_CC
+ arm_SMUAD_X_MI
+ arm_SMUAD_X_PL
+ arm_SMUAD_X_VS
+ arm_SMUAD_X_VC
+ arm_SMUAD_X_HI
+ arm_SMUAD_X_LS
+ arm_SMUAD_X_GE
+ arm_SMUAD_X_LT
+ arm_SMUAD_X_GT
+ arm_SMUAD_X_LE
+ arm_SMUAD_X
+ arm_SMUAD_X_ZZ
+ arm_SMULBB_EQ
+ arm_SMULBB_NE
+ arm_SMULBB_CS
+ arm_SMULBB_CC
+ arm_SMULBB_MI
+ arm_SMULBB_PL
+ arm_SMULBB_VS
+ arm_SMULBB_VC
+ arm_SMULBB_HI
+ arm_SMULBB_LS
+ arm_SMULBB_GE
+ arm_SMULBB_LT
+ arm_SMULBB_GT
+ arm_SMULBB_LE
+ arm_SMULBB
+ arm_SMULBB_ZZ
+ arm_SMULBT_EQ
+ arm_SMULBT_NE
+ arm_SMULBT_CS
+ arm_SMULBT_CC
+ arm_SMULBT_MI
+ arm_SMULBT_PL
+ arm_SMULBT_VS
+ arm_SMULBT_VC
+ arm_SMULBT_HI
+ arm_SMULBT_LS
+ arm_SMULBT_GE
+ arm_SMULBT_LT
+ arm_SMULBT_GT
+ arm_SMULBT_LE
+ arm_SMULBT
+ arm_SMULBT_ZZ
+ arm_SMULTB_EQ
+ arm_SMULTB_NE
+ arm_SMULTB_CS
+ arm_SMULTB_CC
+ arm_SMULTB_MI
+ arm_SMULTB_PL
+ arm_SMULTB_VS
+ arm_SMULTB_VC
+ arm_SMULTB_HI
+ arm_SMULTB_LS
+ arm_SMULTB_GE
+ arm_SMULTB_LT
+ arm_SMULTB_GT
+ arm_SMULTB_LE
+ arm_SMULTB
+ arm_SMULTB_ZZ
+ arm_SMULTT_EQ
+ arm_SMULTT_NE
+ arm_SMULTT_CS
+ arm_SMULTT_CC
+ arm_SMULTT_MI
+ arm_SMULTT_PL
+ arm_SMULTT_VS
+ arm_SMULTT_VC
+ arm_SMULTT_HI
+ arm_SMULTT_LS
+ arm_SMULTT_GE
+ arm_SMULTT_LT
+ arm_SMULTT_GT
+ arm_SMULTT_LE
+ arm_SMULTT
+ arm_SMULTT_ZZ
+ arm_SMULL_EQ
+ arm_SMULL_NE
+ arm_SMULL_CS
+ arm_SMULL_CC
+ arm_SMULL_MI
+ arm_SMULL_PL
+ arm_SMULL_VS
+ arm_SMULL_VC
+ arm_SMULL_HI
+ arm_SMULL_LS
+ arm_SMULL_GE
+ arm_SMULL_LT
+ arm_SMULL_GT
+ arm_SMULL_LE
+ arm_SMULL
+ arm_SMULL_ZZ
+ arm_SMULL_S_EQ
+ arm_SMULL_S_NE
+ arm_SMULL_S_CS
+ arm_SMULL_S_CC
+ arm_SMULL_S_MI
+ arm_SMULL_S_PL
+ arm_SMULL_S_VS
+ arm_SMULL_S_VC
+ arm_SMULL_S_HI
+ arm_SMULL_S_LS
+ arm_SMULL_S_GE
+ arm_SMULL_S_LT
+ arm_SMULL_S_GT
+ arm_SMULL_S_LE
+ arm_SMULL_S
+ arm_SMULL_S_ZZ
+ arm_SMULWB_EQ
+ arm_SMULWB_NE
+ arm_SMULWB_CS
+ arm_SMULWB_CC
+ arm_SMULWB_MI
+ arm_SMULWB_PL
+ arm_SMULWB_VS
+ arm_SMULWB_VC
+ arm_SMULWB_HI
+ arm_SMULWB_LS
+ arm_SMULWB_GE
+ arm_SMULWB_LT
+ arm_SMULWB_GT
+ arm_SMULWB_LE
+ arm_SMULWB
+ arm_SMULWB_ZZ
+ arm_SMULWT_EQ
+ arm_SMULWT_NE
+ arm_SMULWT_CS
+ arm_SMULWT_CC
+ arm_SMULWT_MI
+ arm_SMULWT_PL
+ arm_SMULWT_VS
+ arm_SMULWT_VC
+ arm_SMULWT_HI
+ arm_SMULWT_LS
+ arm_SMULWT_GE
+ arm_SMULWT_LT
+ arm_SMULWT_GT
+ arm_SMULWT_LE
+ arm_SMULWT
+ arm_SMULWT_ZZ
+ arm_SMUSD_EQ
+ arm_SMUSD_NE
+ arm_SMUSD_CS
+ arm_SMUSD_CC
+ arm_SMUSD_MI
+ arm_SMUSD_PL
+ arm_SMUSD_VS
+ arm_SMUSD_VC
+ arm_SMUSD_HI
+ arm_SMUSD_LS
+ arm_SMUSD_GE
+ arm_SMUSD_LT
+ arm_SMUSD_GT
+ arm_SMUSD_LE
+ arm_SMUSD
+ arm_SMUSD_ZZ
+ arm_SMUSD_X_EQ
+ arm_SMUSD_X_NE
+ arm_SMUSD_X_CS
+ arm_SMUSD_X_CC
+ arm_SMUSD_X_MI
+ arm_SMUSD_X_PL
+ arm_SMUSD_X_VS
+ arm_SMUSD_X_VC
+ arm_SMUSD_X_HI
+ arm_SMUSD_X_LS
+ arm_SMUSD_X_GE
+ arm_SMUSD_X_LT
+ arm_SMUSD_X_GT
+ arm_SMUSD_X_LE
+ arm_SMUSD_X
+ arm_SMUSD_X_ZZ
+ arm_SSAT_EQ
+ arm_SSAT_NE
+ arm_SSAT_CS
+ arm_SSAT_CC
+ arm_SSAT_MI
+ arm_SSAT_PL
+ arm_SSAT_VS
+ arm_SSAT_VC
+ arm_SSAT_HI
+ arm_SSAT_LS
+ arm_SSAT_GE
+ arm_SSAT_LT
+ arm_SSAT_GT
+ arm_SSAT_LE
+ arm_SSAT
+ arm_SSAT_ZZ
+ arm_SSAT16_EQ
+ arm_SSAT16_NE
+ arm_SSAT16_CS
+ arm_SSAT16_CC
+ arm_SSAT16_MI
+ arm_SSAT16_PL
+ arm_SSAT16_VS
+ arm_SSAT16_VC
+ arm_SSAT16_HI
+ arm_SSAT16_LS
+ arm_SSAT16_GE
+ arm_SSAT16_LT
+ arm_SSAT16_GT
+ arm_SSAT16_LE
+ arm_SSAT16
+ arm_SSAT16_ZZ
+ arm_SSAX_EQ
+ arm_SSAX_NE
+ arm_SSAX_CS
+ arm_SSAX_CC
+ arm_SSAX_MI
+ arm_SSAX_PL
+ arm_SSAX_VS
+ arm_SSAX_VC
+ arm_SSAX_HI
+ arm_SSAX_LS
+ arm_SSAX_GE
+ arm_SSAX_LT
+ arm_SSAX_GT
+ arm_SSAX_LE
+ arm_SSAX
+ arm_SSAX_ZZ
+ arm_SSUB16_EQ
+ arm_SSUB16_NE
+ arm_SSUB16_CS
+ arm_SSUB16_CC
+ arm_SSUB16_MI
+ arm_SSUB16_PL
+ arm_SSUB16_VS
+ arm_SSUB16_VC
+ arm_SSUB16_HI
+ arm_SSUB16_LS
+ arm_SSUB16_GE
+ arm_SSUB16_LT
+ arm_SSUB16_GT
+ arm_SSUB16_LE
+ arm_SSUB16
+ arm_SSUB16_ZZ
+ arm_SSUB8_EQ
+ arm_SSUB8_NE
+ arm_SSUB8_CS
+ arm_SSUB8_CC
+ arm_SSUB8_MI
+ arm_SSUB8_PL
+ arm_SSUB8_VS
+ arm_SSUB8_VC
+ arm_SSUB8_HI
+ arm_SSUB8_LS
+ arm_SSUB8_GE
+ arm_SSUB8_LT
+ arm_SSUB8_GT
+ arm_SSUB8_LE
+ arm_SSUB8
+ arm_SSUB8_ZZ
+ arm_STM_EQ
+ arm_STM_NE
+ arm_STM_CS
+ arm_STM_CC
+ arm_STM_MI
+ arm_STM_PL
+ arm_STM_VS
+ arm_STM_VC
+ arm_STM_HI
+ arm_STM_LS
+ arm_STM_GE
+ arm_STM_LT
+ arm_STM_GT
+ arm_STM_LE
+ arm_STM
+ arm_STM_ZZ
+ arm_STMDA_EQ
+ arm_STMDA_NE
+ arm_STMDA_CS
+ arm_STMDA_CC
+ arm_STMDA_MI
+ arm_STMDA_PL
+ arm_STMDA_VS
+ arm_STMDA_VC
+ arm_STMDA_HI
+ arm_STMDA_LS
+ arm_STMDA_GE
+ arm_STMDA_LT
+ arm_STMDA_GT
+ arm_STMDA_LE
+ arm_STMDA
+ arm_STMDA_ZZ
+ arm_STMDB_EQ
+ arm_STMDB_NE
+ arm_STMDB_CS
+ arm_STMDB_CC
+ arm_STMDB_MI
+ arm_STMDB_PL
+ arm_STMDB_VS
+ arm_STMDB_VC
+ arm_STMDB_HI
+ arm_STMDB_LS
+ arm_STMDB_GE
+ arm_STMDB_LT
+ arm_STMDB_GT
+ arm_STMDB_LE
+ arm_STMDB
+ arm_STMDB_ZZ
+ arm_STMIB_EQ
+ arm_STMIB_NE
+ arm_STMIB_CS
+ arm_STMIB_CC
+ arm_STMIB_MI
+ arm_STMIB_PL
+ arm_STMIB_VS
+ arm_STMIB_VC
+ arm_STMIB_HI
+ arm_STMIB_LS
+ arm_STMIB_GE
+ arm_STMIB_LT
+ arm_STMIB_GT
+ arm_STMIB_LE
+ arm_STMIB
+ arm_STMIB_ZZ
+ arm_STR_EQ
+ arm_STR_NE
+ arm_STR_CS
+ arm_STR_CC
+ arm_STR_MI
+ arm_STR_PL
+ arm_STR_VS
+ arm_STR_VC
+ arm_STR_HI
+ arm_STR_LS
+ arm_STR_GE
+ arm_STR_LT
+ arm_STR_GT
+ arm_STR_LE
+ arm_STR
+ arm_STR_ZZ
+ arm_STRB_EQ
+ arm_STRB_NE
+ arm_STRB_CS
+ arm_STRB_CC
+ arm_STRB_MI
+ arm_STRB_PL
+ arm_STRB_VS
+ arm_STRB_VC
+ arm_STRB_HI
+ arm_STRB_LS
+ arm_STRB_GE
+ arm_STRB_LT
+ arm_STRB_GT
+ arm_STRB_LE
+ arm_STRB
+ arm_STRB_ZZ
+ arm_STRBT_EQ
+ arm_STRBT_NE
+ arm_STRBT_CS
+ arm_STRBT_CC
+ arm_STRBT_MI
+ arm_STRBT_PL
+ arm_STRBT_VS
+ arm_STRBT_VC
+ arm_STRBT_HI
+ arm_STRBT_LS
+ arm_STRBT_GE
+ arm_STRBT_LT
+ arm_STRBT_GT
+ arm_STRBT_LE
+ arm_STRBT
+ arm_STRBT_ZZ
+ arm_STRD_EQ
+ arm_STRD_NE
+ arm_STRD_CS
+ arm_STRD_CC
+ arm_STRD_MI
+ arm_STRD_PL
+ arm_STRD_VS
+ arm_STRD_VC
+ arm_STRD_HI
+ arm_STRD_LS
+ arm_STRD_GE
+ arm_STRD_LT
+ arm_STRD_GT
+ arm_STRD_LE
+ arm_STRD
+ arm_STRD_ZZ
+ arm_STREX_EQ
+ arm_STREX_NE
+ arm_STREX_CS
+ arm_STREX_CC
+ arm_STREX_MI
+ arm_STREX_PL
+ arm_STREX_VS
+ arm_STREX_VC
+ arm_STREX_HI
+ arm_STREX_LS
+ arm_STREX_GE
+ arm_STREX_LT
+ arm_STREX_GT
+ arm_STREX_LE
+ arm_STREX
+ arm_STREX_ZZ
+ arm_STREXB_EQ
+ arm_STREXB_NE
+ arm_STREXB_CS
+ arm_STREXB_CC
+ arm_STREXB_MI
+ arm_STREXB_PL
+ arm_STREXB_VS
+ arm_STREXB_VC
+ arm_STREXB_HI
+ arm_STREXB_LS
+ arm_STREXB_GE
+ arm_STREXB_LT
+ arm_STREXB_GT
+ arm_STREXB_LE
+ arm_STREXB
+ arm_STREXB_ZZ
+ arm_STREXD_EQ
+ arm_STREXD_NE
+ arm_STREXD_CS
+ arm_STREXD_CC
+ arm_STREXD_MI
+ arm_STREXD_PL
+ arm_STREXD_VS
+ arm_STREXD_VC
+ arm_STREXD_HI
+ arm_STREXD_LS
+ arm_STREXD_GE
+ arm_STREXD_LT
+ arm_STREXD_GT
+ arm_STREXD_LE
+ arm_STREXD
+ arm_STREXD_ZZ
+ arm_STREXH_EQ
+ arm_STREXH_NE
+ arm_STREXH_CS
+ arm_STREXH_CC
+ arm_STREXH_MI
+ arm_STREXH_PL
+ arm_STREXH_VS
+ arm_STREXH_VC
+ arm_STREXH_HI
+ arm_STREXH_LS
+ arm_STREXH_GE
+ arm_STREXH_LT
+ arm_STREXH_GT
+ arm_STREXH_LE
+ arm_STREXH
+ arm_STREXH_ZZ
+ arm_STRH_EQ
+ arm_STRH_NE
+ arm_STRH_CS
+ arm_STRH_CC
+ arm_STRH_MI
+ arm_STRH_PL
+ arm_STRH_VS
+ arm_STRH_VC
+ arm_STRH_HI
+ arm_STRH_LS
+ arm_STRH_GE
+ arm_STRH_LT
+ arm_STRH_GT
+ arm_STRH_LE
+ arm_STRH
+ arm_STRH_ZZ
+ arm_STRHT_EQ
+ arm_STRHT_NE
+ arm_STRHT_CS
+ arm_STRHT_CC
+ arm_STRHT_MI
+ arm_STRHT_PL
+ arm_STRHT_VS
+ arm_STRHT_VC
+ arm_STRHT_HI
+ arm_STRHT_LS
+ arm_STRHT_GE
+ arm_STRHT_LT
+ arm_STRHT_GT
+ arm_STRHT_LE
+ arm_STRHT
+ arm_STRHT_ZZ
+ arm_STRT_EQ
+ arm_STRT_NE
+ arm_STRT_CS
+ arm_STRT_CC
+ arm_STRT_MI
+ arm_STRT_PL
+ arm_STRT_VS
+ arm_STRT_VC
+ arm_STRT_HI
+ arm_STRT_LS
+ arm_STRT_GE
+ arm_STRT_LT
+ arm_STRT_GT
+ arm_STRT_LE
+ arm_STRT
+ arm_STRT_ZZ
+ arm_SUB_EQ
+ arm_SUB_NE
+ arm_SUB_CS
+ arm_SUB_CC
+ arm_SUB_MI
+ arm_SUB_PL
+ arm_SUB_VS
+ arm_SUB_VC
+ arm_SUB_HI
+ arm_SUB_LS
+ arm_SUB_GE
+ arm_SUB_LT
+ arm_SUB_GT
+ arm_SUB_LE
+ arm_SUB
+ arm_SUB_ZZ
+ arm_SUB_S_EQ
+ arm_SUB_S_NE
+ arm_SUB_S_CS
+ arm_SUB_S_CC
+ arm_SUB_S_MI
+ arm_SUB_S_PL
+ arm_SUB_S_VS
+ arm_SUB_S_VC
+ arm_SUB_S_HI
+ arm_SUB_S_LS
+ arm_SUB_S_GE
+ arm_SUB_S_LT
+ arm_SUB_S_GT
+ arm_SUB_S_LE
+ arm_SUB_S
+ arm_SUB_S_ZZ
+ arm_SVC_EQ
+ arm_SVC_NE
+ arm_SVC_CS
+ arm_SVC_CC
+ arm_SVC_MI
+ arm_SVC_PL
+ arm_SVC_VS
+ arm_SVC_VC
+ arm_SVC_HI
+ arm_SVC_LS
+ arm_SVC_GE
+ arm_SVC_LT
+ arm_SVC_GT
+ arm_SVC_LE
+ arm_SVC
+ arm_SVC_ZZ
+ arm_SWP_EQ
+ arm_SWP_NE
+ arm_SWP_CS
+ arm_SWP_CC
+ arm_SWP_MI
+ arm_SWP_PL
+ arm_SWP_VS
+ arm_SWP_VC
+ arm_SWP_HI
+ arm_SWP_LS
+ arm_SWP_GE
+ arm_SWP_LT
+ arm_SWP_GT
+ arm_SWP_LE
+ arm_SWP
+ arm_SWP_ZZ
+ arm_SWP_B_EQ
+ arm_SWP_B_NE
+ arm_SWP_B_CS
+ arm_SWP_B_CC
+ arm_SWP_B_MI
+ arm_SWP_B_PL
+ arm_SWP_B_VS
+ arm_SWP_B_VC
+ arm_SWP_B_HI
+ arm_SWP_B_LS
+ arm_SWP_B_GE
+ arm_SWP_B_LT
+ arm_SWP_B_GT
+ arm_SWP_B_LE
+ arm_SWP_B
+ arm_SWP_B_ZZ
+ arm_SXTAB_EQ
+ arm_SXTAB_NE
+ arm_SXTAB_CS
+ arm_SXTAB_CC
+ arm_SXTAB_MI
+ arm_SXTAB_PL
+ arm_SXTAB_VS
+ arm_SXTAB_VC
+ arm_SXTAB_HI
+ arm_SXTAB_LS
+ arm_SXTAB_GE
+ arm_SXTAB_LT
+ arm_SXTAB_GT
+ arm_SXTAB_LE
+ arm_SXTAB
+ arm_SXTAB_ZZ
+ arm_SXTAB16_EQ
+ arm_SXTAB16_NE
+ arm_SXTAB16_CS
+ arm_SXTAB16_CC
+ arm_SXTAB16_MI
+ arm_SXTAB16_PL
+ arm_SXTAB16_VS
+ arm_SXTAB16_VC
+ arm_SXTAB16_HI
+ arm_SXTAB16_LS
+ arm_SXTAB16_GE
+ arm_SXTAB16_LT
+ arm_SXTAB16_GT
+ arm_SXTAB16_LE
+ arm_SXTAB16
+ arm_SXTAB16_ZZ
+ arm_SXTAH_EQ
+ arm_SXTAH_NE
+ arm_SXTAH_CS
+ arm_SXTAH_CC
+ arm_SXTAH_MI
+ arm_SXTAH_PL
+ arm_SXTAH_VS
+ arm_SXTAH_VC
+ arm_SXTAH_HI
+ arm_SXTAH_LS
+ arm_SXTAH_GE
+ arm_SXTAH_LT
+ arm_SXTAH_GT
+ arm_SXTAH_LE
+ arm_SXTAH
+ arm_SXTAH_ZZ
+ arm_SXTB_EQ
+ arm_SXTB_NE
+ arm_SXTB_CS
+ arm_SXTB_CC
+ arm_SXTB_MI
+ arm_SXTB_PL
+ arm_SXTB_VS
+ arm_SXTB_VC
+ arm_SXTB_HI
+ arm_SXTB_LS
+ arm_SXTB_GE
+ arm_SXTB_LT
+ arm_SXTB_GT
+ arm_SXTB_LE
+ arm_SXTB
+ arm_SXTB_ZZ
+ arm_SXTB16_EQ
+ arm_SXTB16_NE
+ arm_SXTB16_CS
+ arm_SXTB16_CC
+ arm_SXTB16_MI
+ arm_SXTB16_PL
+ arm_SXTB16_VS
+ arm_SXTB16_VC
+ arm_SXTB16_HI
+ arm_SXTB16_LS
+ arm_SXTB16_GE
+ arm_SXTB16_LT
+ arm_SXTB16_GT
+ arm_SXTB16_LE
+ arm_SXTB16
+ arm_SXTB16_ZZ
+ arm_SXTH_EQ
+ arm_SXTH_NE
+ arm_SXTH_CS
+ arm_SXTH_CC
+ arm_SXTH_MI
+ arm_SXTH_PL
+ arm_SXTH_VS
+ arm_SXTH_VC
+ arm_SXTH_HI
+ arm_SXTH_LS
+ arm_SXTH_GE
+ arm_SXTH_LT
+ arm_SXTH_GT
+ arm_SXTH_LE
+ arm_SXTH
+ arm_SXTH_ZZ
+ arm_TEQ_EQ
+ arm_TEQ_NE
+ arm_TEQ_CS
+ arm_TEQ_CC
+ arm_TEQ_MI
+ arm_TEQ_PL
+ arm_TEQ_VS
+ arm_TEQ_VC
+ arm_TEQ_HI
+ arm_TEQ_LS
+ arm_TEQ_GE
+ arm_TEQ_LT
+ arm_TEQ_GT
+ arm_TEQ_LE
+ arm_TEQ
+ arm_TEQ_ZZ
+ arm_TST_EQ
+ arm_TST_NE
+ arm_TST_CS
+ arm_TST_CC
+ arm_TST_MI
+ arm_TST_PL
+ arm_TST_VS
+ arm_TST_VC
+ arm_TST_HI
+ arm_TST_LS
+ arm_TST_GE
+ arm_TST_LT
+ arm_TST_GT
+ arm_TST_LE
+ arm_TST
+ arm_TST_ZZ
+ arm_UADD16_EQ
+ arm_UADD16_NE
+ arm_UADD16_CS
+ arm_UADD16_CC
+ arm_UADD16_MI
+ arm_UADD16_PL
+ arm_UADD16_VS
+ arm_UADD16_VC
+ arm_UADD16_HI
+ arm_UADD16_LS
+ arm_UADD16_GE
+ arm_UADD16_LT
+ arm_UADD16_GT
+ arm_UADD16_LE
+ arm_UADD16
+ arm_UADD16_ZZ
+ arm_UADD8_EQ
+ arm_UADD8_NE
+ arm_UADD8_CS
+ arm_UADD8_CC
+ arm_UADD8_MI
+ arm_UADD8_PL
+ arm_UADD8_VS
+ arm_UADD8_VC
+ arm_UADD8_HI
+ arm_UADD8_LS
+ arm_UADD8_GE
+ arm_UADD8_LT
+ arm_UADD8_GT
+ arm_UADD8_LE
+ arm_UADD8
+ arm_UADD8_ZZ
+ arm_UASX_EQ
+ arm_UASX_NE
+ arm_UASX_CS
+ arm_UASX_CC
+ arm_UASX_MI
+ arm_UASX_PL
+ arm_UASX_VS
+ arm_UASX_VC
+ arm_UASX_HI
+ arm_UASX_LS
+ arm_UASX_GE
+ arm_UASX_LT
+ arm_UASX_GT
+ arm_UASX_LE
+ arm_UASX
+ arm_UASX_ZZ
+ arm_UBFX_EQ
+ arm_UBFX_NE
+ arm_UBFX_CS
+ arm_UBFX_CC
+ arm_UBFX_MI
+ arm_UBFX_PL
+ arm_UBFX_VS
+ arm_UBFX_VC
+ arm_UBFX_HI
+ arm_UBFX_LS
+ arm_UBFX_GE
+ arm_UBFX_LT
+ arm_UBFX_GT
+ arm_UBFX_LE
+ arm_UBFX
+ arm_UBFX_ZZ
+ arm_UHADD16_EQ
+ arm_UHADD16_NE
+ arm_UHADD16_CS
+ arm_UHADD16_CC
+ arm_UHADD16_MI
+ arm_UHADD16_PL
+ arm_UHADD16_VS
+ arm_UHADD16_VC
+ arm_UHADD16_HI
+ arm_UHADD16_LS
+ arm_UHADD16_GE
+ arm_UHADD16_LT
+ arm_UHADD16_GT
+ arm_UHADD16_LE
+ arm_UHADD16
+ arm_UHADD16_ZZ
+ arm_UHADD8_EQ
+ arm_UHADD8_NE
+ arm_UHADD8_CS
+ arm_UHADD8_CC
+ arm_UHADD8_MI
+ arm_UHADD8_PL
+ arm_UHADD8_VS
+ arm_UHADD8_VC
+ arm_UHADD8_HI
+ arm_UHADD8_LS
+ arm_UHADD8_GE
+ arm_UHADD8_LT
+ arm_UHADD8_GT
+ arm_UHADD8_LE
+ arm_UHADD8
+ arm_UHADD8_ZZ
+ arm_UHASX_EQ
+ arm_UHASX_NE
+ arm_UHASX_CS
+ arm_UHASX_CC
+ arm_UHASX_MI
+ arm_UHASX_PL
+ arm_UHASX_VS
+ arm_UHASX_VC
+ arm_UHASX_HI
+ arm_UHASX_LS
+ arm_UHASX_GE
+ arm_UHASX_LT
+ arm_UHASX_GT
+ arm_UHASX_LE
+ arm_UHASX
+ arm_UHASX_ZZ
+ arm_UHSAX_EQ
+ arm_UHSAX_NE
+ arm_UHSAX_CS
+ arm_UHSAX_CC
+ arm_UHSAX_MI
+ arm_UHSAX_PL
+ arm_UHSAX_VS
+ arm_UHSAX_VC
+ arm_UHSAX_HI
+ arm_UHSAX_LS
+ arm_UHSAX_GE
+ arm_UHSAX_LT
+ arm_UHSAX_GT
+ arm_UHSAX_LE
+ arm_UHSAX
+ arm_UHSAX_ZZ
+ arm_UHSUB16_EQ
+ arm_UHSUB16_NE
+ arm_UHSUB16_CS
+ arm_UHSUB16_CC
+ arm_UHSUB16_MI
+ arm_UHSUB16_PL
+ arm_UHSUB16_VS
+ arm_UHSUB16_VC
+ arm_UHSUB16_HI
+ arm_UHSUB16_LS
+ arm_UHSUB16_GE
+ arm_UHSUB16_LT
+ arm_UHSUB16_GT
+ arm_UHSUB16_LE
+ arm_UHSUB16
+ arm_UHSUB16_ZZ
+ arm_UHSUB8_EQ
+ arm_UHSUB8_NE
+ arm_UHSUB8_CS
+ arm_UHSUB8_CC
+ arm_UHSUB8_MI
+ arm_UHSUB8_PL
+ arm_UHSUB8_VS
+ arm_UHSUB8_VC
+ arm_UHSUB8_HI
+ arm_UHSUB8_LS
+ arm_UHSUB8_GE
+ arm_UHSUB8_LT
+ arm_UHSUB8_GT
+ arm_UHSUB8_LE
+ arm_UHSUB8
+ arm_UHSUB8_ZZ
+ arm_UMAAL_EQ
+ arm_UMAAL_NE
+ arm_UMAAL_CS
+ arm_UMAAL_CC
+ arm_UMAAL_MI
+ arm_UMAAL_PL
+ arm_UMAAL_VS
+ arm_UMAAL_VC
+ arm_UMAAL_HI
+ arm_UMAAL_LS
+ arm_UMAAL_GE
+ arm_UMAAL_LT
+ arm_UMAAL_GT
+ arm_UMAAL_LE
+ arm_UMAAL
+ arm_UMAAL_ZZ
+ arm_UMLAL_EQ
+ arm_UMLAL_NE
+ arm_UMLAL_CS
+ arm_UMLAL_CC
+ arm_UMLAL_MI
+ arm_UMLAL_PL
+ arm_UMLAL_VS
+ arm_UMLAL_VC
+ arm_UMLAL_HI
+ arm_UMLAL_LS
+ arm_UMLAL_GE
+ arm_UMLAL_LT
+ arm_UMLAL_GT
+ arm_UMLAL_LE
+ arm_UMLAL
+ arm_UMLAL_ZZ
+ arm_UMLAL_S_EQ
+ arm_UMLAL_S_NE
+ arm_UMLAL_S_CS
+ arm_UMLAL_S_CC
+ arm_UMLAL_S_MI
+ arm_UMLAL_S_PL
+ arm_UMLAL_S_VS
+ arm_UMLAL_S_VC
+ arm_UMLAL_S_HI
+ arm_UMLAL_S_LS
+ arm_UMLAL_S_GE
+ arm_UMLAL_S_LT
+ arm_UMLAL_S_GT
+ arm_UMLAL_S_LE
+ arm_UMLAL_S
+ arm_UMLAL_S_ZZ
+ arm_UMULL_EQ
+ arm_UMULL_NE
+ arm_UMULL_CS
+ arm_UMULL_CC
+ arm_UMULL_MI
+ arm_UMULL_PL
+ arm_UMULL_VS
+ arm_UMULL_VC
+ arm_UMULL_HI
+ arm_UMULL_LS
+ arm_UMULL_GE
+ arm_UMULL_LT
+ arm_UMULL_GT
+ arm_UMULL_LE
+ arm_UMULL
+ arm_UMULL_ZZ
+ arm_UMULL_S_EQ
+ arm_UMULL_S_NE
+ arm_UMULL_S_CS
+ arm_UMULL_S_CC
+ arm_UMULL_S_MI
+ arm_UMULL_S_PL
+ arm_UMULL_S_VS
+ arm_UMULL_S_VC
+ arm_UMULL_S_HI
+ arm_UMULL_S_LS
+ arm_UMULL_S_GE
+ arm_UMULL_S_LT
+ arm_UMULL_S_GT
+ arm_UMULL_S_LE
+ arm_UMULL_S
+ arm_UMULL_S_ZZ
+ arm_UNDEF
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ _
+ arm_UQADD16_EQ
+ arm_UQADD16_NE
+ arm_UQADD16_CS
+ arm_UQADD16_CC
+ arm_UQADD16_MI
+ arm_UQADD16_PL
+ arm_UQADD16_VS
+ arm_UQADD16_VC
+ arm_UQADD16_HI
+ arm_UQADD16_LS
+ arm_UQADD16_GE
+ arm_UQADD16_LT
+ arm_UQADD16_GT
+ arm_UQADD16_LE
+ arm_UQADD16
+ arm_UQADD16_ZZ
+ arm_UQADD8_EQ
+ arm_UQADD8_NE
+ arm_UQADD8_CS
+ arm_UQADD8_CC
+ arm_UQADD8_MI
+ arm_UQADD8_PL
+ arm_UQADD8_VS
+ arm_UQADD8_VC
+ arm_UQADD8_HI
+ arm_UQADD8_LS
+ arm_UQADD8_GE
+ arm_UQADD8_LT
+ arm_UQADD8_GT
+ arm_UQADD8_LE
+ arm_UQADD8
+ arm_UQADD8_ZZ
+ arm_UQASX_EQ
+ arm_UQASX_NE
+ arm_UQASX_CS
+ arm_UQASX_CC
+ arm_UQASX_MI
+ arm_UQASX_PL
+ arm_UQASX_VS
+ arm_UQASX_VC
+ arm_UQASX_HI
+ arm_UQASX_LS
+ arm_UQASX_GE
+ arm_UQASX_LT
+ arm_UQASX_GT
+ arm_UQASX_LE
+ arm_UQASX
+ arm_UQASX_ZZ
+ arm_UQSAX_EQ
+ arm_UQSAX_NE
+ arm_UQSAX_CS
+ arm_UQSAX_CC
+ arm_UQSAX_MI
+ arm_UQSAX_PL
+ arm_UQSAX_VS
+ arm_UQSAX_VC
+ arm_UQSAX_HI
+ arm_UQSAX_LS
+ arm_UQSAX_GE
+ arm_UQSAX_LT
+ arm_UQSAX_GT
+ arm_UQSAX_LE
+ arm_UQSAX
+ arm_UQSAX_ZZ
+ arm_UQSUB16_EQ
+ arm_UQSUB16_NE
+ arm_UQSUB16_CS
+ arm_UQSUB16_CC
+ arm_UQSUB16_MI
+ arm_UQSUB16_PL
+ arm_UQSUB16_VS
+ arm_UQSUB16_VC
+ arm_UQSUB16_HI
+ arm_UQSUB16_LS
+ arm_UQSUB16_GE
+ arm_UQSUB16_LT
+ arm_UQSUB16_GT
+ arm_UQSUB16_LE
+ arm_UQSUB16
+ arm_UQSUB16_ZZ
+ arm_UQSUB8_EQ
+ arm_UQSUB8_NE
+ arm_UQSUB8_CS
+ arm_UQSUB8_CC
+ arm_UQSUB8_MI
+ arm_UQSUB8_PL
+ arm_UQSUB8_VS
+ arm_UQSUB8_VC
+ arm_UQSUB8_HI
+ arm_UQSUB8_LS
+ arm_UQSUB8_GE
+ arm_UQSUB8_LT
+ arm_UQSUB8_GT
+ arm_UQSUB8_LE
+ arm_UQSUB8
+ arm_UQSUB8_ZZ
+ arm_USAD8_EQ
+ arm_USAD8_NE
+ arm_USAD8_CS
+ arm_USAD8_CC
+ arm_USAD8_MI
+ arm_USAD8_PL
+ arm_USAD8_VS
+ arm_USAD8_VC
+ arm_USAD8_HI
+ arm_USAD8_LS
+ arm_USAD8_GE
+ arm_USAD8_LT
+ arm_USAD8_GT
+ arm_USAD8_LE
+ arm_USAD8
+ arm_USAD8_ZZ
+ arm_USADA8_EQ
+ arm_USADA8_NE
+ arm_USADA8_CS
+ arm_USADA8_CC
+ arm_USADA8_MI
+ arm_USADA8_PL
+ arm_USADA8_VS
+ arm_USADA8_VC
+ arm_USADA8_HI
+ arm_USADA8_LS
+ arm_USADA8_GE
+ arm_USADA8_LT
+ arm_USADA8_GT
+ arm_USADA8_LE
+ arm_USADA8
+ arm_USADA8_ZZ
+ arm_USAT_EQ
+ arm_USAT_NE
+ arm_USAT_CS
+ arm_USAT_CC
+ arm_USAT_MI
+ arm_USAT_PL
+ arm_USAT_VS
+ arm_USAT_VC
+ arm_USAT_HI
+ arm_USAT_LS
+ arm_USAT_GE
+ arm_USAT_LT
+ arm_USAT_GT
+ arm_USAT_LE
+ arm_USAT
+ arm_USAT_ZZ
+ arm_USAT16_EQ
+ arm_USAT16_NE
+ arm_USAT16_CS
+ arm_USAT16_CC
+ arm_USAT16_MI
+ arm_USAT16_PL
+ arm_USAT16_VS
+ arm_USAT16_VC
+ arm_USAT16_HI
+ arm_USAT16_LS
+ arm_USAT16_GE
+ arm_USAT16_LT
+ arm_USAT16_GT
+ arm_USAT16_LE
+ arm_USAT16
+ arm_USAT16_ZZ
+ arm_USAX_EQ
+ arm_USAX_NE
+ arm_USAX_CS
+ arm_USAX_CC
+ arm_USAX_MI
+ arm_USAX_PL
+ arm_USAX_VS
+ arm_USAX_VC
+ arm_USAX_HI
+ arm_USAX_LS
+ arm_USAX_GE
+ arm_USAX_LT
+ arm_USAX_GT
+ arm_USAX_LE
+ arm_USAX
+ arm_USAX_ZZ
+ arm_USUB16_EQ
+ arm_USUB16_NE
+ arm_USUB16_CS
+ arm_USUB16_CC
+ arm_USUB16_MI
+ arm_USUB16_PL
+ arm_USUB16_VS
+ arm_USUB16_VC
+ arm_USUB16_HI
+ arm_USUB16_LS
+ arm_USUB16_GE
+ arm_USUB16_LT
+ arm_USUB16_GT
+ arm_USUB16_LE
+ arm_USUB16
+ arm_USUB16_ZZ
+ arm_USUB8_EQ
+ arm_USUB8_NE
+ arm_USUB8_CS
+ arm_USUB8_CC
+ arm_USUB8_MI
+ arm_USUB8_PL
+ arm_USUB8_VS
+ arm_USUB8_VC
+ arm_USUB8_HI
+ arm_USUB8_LS
+ arm_USUB8_GE
+ arm_USUB8_LT
+ arm_USUB8_GT
+ arm_USUB8_LE
+ arm_USUB8
+ arm_USUB8_ZZ
+ arm_UXTAB_EQ
+ arm_UXTAB_NE
+ arm_UXTAB_CS
+ arm_UXTAB_CC
+ arm_UXTAB_MI
+ arm_UXTAB_PL
+ arm_UXTAB_VS
+ arm_UXTAB_VC
+ arm_UXTAB_HI
+ arm_UXTAB_LS
+ arm_UXTAB_GE
+ arm_UXTAB_LT
+ arm_UXTAB_GT
+ arm_UXTAB_LE
+ arm_UXTAB
+ arm_UXTAB_ZZ
+ arm_UXTAB16_EQ
+ arm_UXTAB16_NE
+ arm_UXTAB16_CS
+ arm_UXTAB16_CC
+ arm_UXTAB16_MI
+ arm_UXTAB16_PL
+ arm_UXTAB16_VS
+ arm_UXTAB16_VC
+ arm_UXTAB16_HI
+ arm_UXTAB16_LS
+ arm_UXTAB16_GE
+ arm_UXTAB16_LT
+ arm_UXTAB16_GT
+ arm_UXTAB16_LE
+ arm_UXTAB16
+ arm_UXTAB16_ZZ
+ arm_UXTAH_EQ
+ arm_UXTAH_NE
+ arm_UXTAH_CS
+ arm_UXTAH_CC
+ arm_UXTAH_MI
+ arm_UXTAH_PL
+ arm_UXTAH_VS
+ arm_UXTAH_VC
+ arm_UXTAH_HI
+ arm_UXTAH_LS
+ arm_UXTAH_GE
+ arm_UXTAH_LT
+ arm_UXTAH_GT
+ arm_UXTAH_LE
+ arm_UXTAH
+ arm_UXTAH_ZZ
+ arm_UXTB_EQ
+ arm_UXTB_NE
+ arm_UXTB_CS
+ arm_UXTB_CC
+ arm_UXTB_MI
+ arm_UXTB_PL
+ arm_UXTB_VS
+ arm_UXTB_VC
+ arm_UXTB_HI
+ arm_UXTB_LS
+ arm_UXTB_GE
+ arm_UXTB_LT
+ arm_UXTB_GT
+ arm_UXTB_LE
+ arm_UXTB
+ arm_UXTB_ZZ
+ arm_UXTB16_EQ
+ arm_UXTB16_NE
+ arm_UXTB16_CS
+ arm_UXTB16_CC
+ arm_UXTB16_MI
+ arm_UXTB16_PL
+ arm_UXTB16_VS
+ arm_UXTB16_VC
+ arm_UXTB16_HI
+ arm_UXTB16_LS
+ arm_UXTB16_GE
+ arm_UXTB16_LT
+ arm_UXTB16_GT
+ arm_UXTB16_LE
+ arm_UXTB16
+ arm_UXTB16_ZZ
+ arm_UXTH_EQ
+ arm_UXTH_NE
+ arm_UXTH_CS
+ arm_UXTH_CC
+ arm_UXTH_MI
+ arm_UXTH_PL
+ arm_UXTH_VS
+ arm_UXTH_VC
+ arm_UXTH_HI
+ arm_UXTH_LS
+ arm_UXTH_GE
+ arm_UXTH_LT
+ arm_UXTH_GT
+ arm_UXTH_LE
+ arm_UXTH
+ arm_UXTH_ZZ
+ arm_VABS_EQ_F32
+ arm_VABS_NE_F32
+ arm_VABS_CS_F32
+ arm_VABS_CC_F32
+ arm_VABS_MI_F32
+ arm_VABS_PL_F32
+ arm_VABS_VS_F32
+ arm_VABS_VC_F32
+ arm_VABS_HI_F32
+ arm_VABS_LS_F32
+ arm_VABS_GE_F32
+ arm_VABS_LT_F32
+ arm_VABS_GT_F32
+ arm_VABS_LE_F32
+ arm_VABS_F32
+ arm_VABS_ZZ_F32
+ arm_VABS_EQ_F64
+ arm_VABS_NE_F64
+ arm_VABS_CS_F64
+ arm_VABS_CC_F64
+ arm_VABS_MI_F64
+ arm_VABS_PL_F64
+ arm_VABS_VS_F64
+ arm_VABS_VC_F64
+ arm_VABS_HI_F64
+ arm_VABS_LS_F64
+ arm_VABS_GE_F64
+ arm_VABS_LT_F64
+ arm_VABS_GT_F64
+ arm_VABS_LE_F64
+ arm_VABS_F64
+ arm_VABS_ZZ_F64
+ arm_VADD_EQ_F32
+ arm_VADD_NE_F32
+ arm_VADD_CS_F32
+ arm_VADD_CC_F32
+ arm_VADD_MI_F32
+ arm_VADD_PL_F32
+ arm_VADD_VS_F32
+ arm_VADD_VC_F32
+ arm_VADD_HI_F32
+ arm_VADD_LS_F32
+ arm_VADD_GE_F32
+ arm_VADD_LT_F32
+ arm_VADD_GT_F32
+ arm_VADD_LE_F32
+ arm_VADD_F32
+ arm_VADD_ZZ_F32
+ arm_VADD_EQ_F64
+ arm_VADD_NE_F64
+ arm_VADD_CS_F64
+ arm_VADD_CC_F64
+ arm_VADD_MI_F64
+ arm_VADD_PL_F64
+ arm_VADD_VS_F64
+ arm_VADD_VC_F64
+ arm_VADD_HI_F64
+ arm_VADD_LS_F64
+ arm_VADD_GE_F64
+ arm_VADD_LT_F64
+ arm_VADD_GT_F64
+ arm_VADD_LE_F64
+ arm_VADD_F64
+ arm_VADD_ZZ_F64
+ arm_VCMP_EQ_F32
+ arm_VCMP_NE_F32
+ arm_VCMP_CS_F32
+ arm_VCMP_CC_F32
+ arm_VCMP_MI_F32
+ arm_VCMP_PL_F32
+ arm_VCMP_VS_F32
+ arm_VCMP_VC_F32
+ arm_VCMP_HI_F32
+ arm_VCMP_LS_F32
+ arm_VCMP_GE_F32
+ arm_VCMP_LT_F32
+ arm_VCMP_GT_F32
+ arm_VCMP_LE_F32
+ arm_VCMP_F32
+ arm_VCMP_ZZ_F32
+ arm_VCMP_EQ_F64
+ arm_VCMP_NE_F64
+ arm_VCMP_CS_F64
+ arm_VCMP_CC_F64
+ arm_VCMP_MI_F64
+ arm_VCMP_PL_F64
+ arm_VCMP_VS_F64
+ arm_VCMP_VC_F64
+ arm_VCMP_HI_F64
+ arm_VCMP_LS_F64
+ arm_VCMP_GE_F64
+ arm_VCMP_LT_F64
+ arm_VCMP_GT_F64
+ arm_VCMP_LE_F64
+ arm_VCMP_F64
+ arm_VCMP_ZZ_F64
+ arm_VCMP_E_EQ_F32
+ arm_VCMP_E_NE_F32
+ arm_VCMP_E_CS_F32
+ arm_VCMP_E_CC_F32
+ arm_VCMP_E_MI_F32
+ arm_VCMP_E_PL_F32
+ arm_VCMP_E_VS_F32
+ arm_VCMP_E_VC_F32
+ arm_VCMP_E_HI_F32
+ arm_VCMP_E_LS_F32
+ arm_VCMP_E_GE_F32
+ arm_VCMP_E_LT_F32
+ arm_VCMP_E_GT_F32
+ arm_VCMP_E_LE_F32
+ arm_VCMP_E_F32
+ arm_VCMP_E_ZZ_F32
+ arm_VCMP_E_EQ_F64
+ arm_VCMP_E_NE_F64
+ arm_VCMP_E_CS_F64
+ arm_VCMP_E_CC_F64
+ arm_VCMP_E_MI_F64
+ arm_VCMP_E_PL_F64
+ arm_VCMP_E_VS_F64
+ arm_VCMP_E_VC_F64
+ arm_VCMP_E_HI_F64
+ arm_VCMP_E_LS_F64
+ arm_VCMP_E_GE_F64
+ arm_VCMP_E_LT_F64
+ arm_VCMP_E_GT_F64
+ arm_VCMP_E_LE_F64
+ arm_VCMP_E_F64
+ arm_VCMP_E_ZZ_F64
+ arm_VCVT_EQ_F32_FXS16
+ arm_VCVT_NE_F32_FXS16
+ arm_VCVT_CS_F32_FXS16
+ arm_VCVT_CC_F32_FXS16
+ arm_VCVT_MI_F32_FXS16
+ arm_VCVT_PL_F32_FXS16
+ arm_VCVT_VS_F32_FXS16
+ arm_VCVT_VC_F32_FXS16
+ arm_VCVT_HI_F32_FXS16
+ arm_VCVT_LS_F32_FXS16
+ arm_VCVT_GE_F32_FXS16
+ arm_VCVT_LT_F32_FXS16
+ arm_VCVT_GT_F32_FXS16
+ arm_VCVT_LE_F32_FXS16
+ arm_VCVT_F32_FXS16
+ arm_VCVT_ZZ_F32_FXS16
+ arm_VCVT_EQ_F32_FXS32
+ arm_VCVT_NE_F32_FXS32
+ arm_VCVT_CS_F32_FXS32
+ arm_VCVT_CC_F32_FXS32
+ arm_VCVT_MI_F32_FXS32
+ arm_VCVT_PL_F32_FXS32
+ arm_VCVT_VS_F32_FXS32
+ arm_VCVT_VC_F32_FXS32
+ arm_VCVT_HI_F32_FXS32
+ arm_VCVT_LS_F32_FXS32
+ arm_VCVT_GE_F32_FXS32
+ arm_VCVT_LT_F32_FXS32
+ arm_VCVT_GT_F32_FXS32
+ arm_VCVT_LE_F32_FXS32
+ arm_VCVT_F32_FXS32
+ arm_VCVT_ZZ_F32_FXS32
+ arm_VCVT_EQ_F32_FXU16
+ arm_VCVT_NE_F32_FXU16
+ arm_VCVT_CS_F32_FXU16
+ arm_VCVT_CC_F32_FXU16
+ arm_VCVT_MI_F32_FXU16
+ arm_VCVT_PL_F32_FXU16
+ arm_VCVT_VS_F32_FXU16
+ arm_VCVT_VC_F32_FXU16
+ arm_VCVT_HI_F32_FXU16
+ arm_VCVT_LS_F32_FXU16
+ arm_VCVT_GE_F32_FXU16
+ arm_VCVT_LT_F32_FXU16
+ arm_VCVT_GT_F32_FXU16
+ arm_VCVT_LE_F32_FXU16
+ arm_VCVT_F32_FXU16
+ arm_VCVT_ZZ_F32_FXU16
+ arm_VCVT_EQ_F32_FXU32
+ arm_VCVT_NE_F32_FXU32
+ arm_VCVT_CS_F32_FXU32
+ arm_VCVT_CC_F32_FXU32
+ arm_VCVT_MI_F32_FXU32
+ arm_VCVT_PL_F32_FXU32
+ arm_VCVT_VS_F32_FXU32
+ arm_VCVT_VC_F32_FXU32
+ arm_VCVT_HI_F32_FXU32
+ arm_VCVT_LS_F32_FXU32
+ arm_VCVT_GE_F32_FXU32
+ arm_VCVT_LT_F32_FXU32
+ arm_VCVT_GT_F32_FXU32
+ arm_VCVT_LE_F32_FXU32
+ arm_VCVT_F32_FXU32
+ arm_VCVT_ZZ_F32_FXU32
+ arm_VCVT_EQ_F64_FXS16
+ arm_VCVT_NE_F64_FXS16
+ arm_VCVT_CS_F64_FXS16
+ arm_VCVT_CC_F64_FXS16
+ arm_VCVT_MI_F64_FXS16
+ arm_VCVT_PL_F64_FXS16
+ arm_VCVT_VS_F64_FXS16
+ arm_VCVT_VC_F64_FXS16
+ arm_VCVT_HI_F64_FXS16
+ arm_VCVT_LS_F64_FXS16
+ arm_VCVT_GE_F64_FXS16
+ arm_VCVT_LT_F64_FXS16
+ arm_VCVT_GT_F64_FXS16
+ arm_VCVT_LE_F64_FXS16
+ arm_VCVT_F64_FXS16
+ arm_VCVT_ZZ_F64_FXS16
+ arm_VCVT_EQ_F64_FXS32
+ arm_VCVT_NE_F64_FXS32
+ arm_VCVT_CS_F64_FXS32
+ arm_VCVT_CC_F64_FXS32
+ arm_VCVT_MI_F64_FXS32
+ arm_VCVT_PL_F64_FXS32
+ arm_VCVT_VS_F64_FXS32
+ arm_VCVT_VC_F64_FXS32
+ arm_VCVT_HI_F64_FXS32
+ arm_VCVT_LS_F64_FXS32
+ arm_VCVT_GE_F64_FXS32
+ arm_VCVT_LT_F64_FXS32
+ arm_VCVT_GT_F64_FXS32
+ arm_VCVT_LE_F64_FXS32
+ arm_VCVT_F64_FXS32
+ arm_VCVT_ZZ_F64_FXS32
+ arm_VCVT_EQ_F64_FXU16
+ arm_VCVT_NE_F64_FXU16
+ arm_VCVT_CS_F64_FXU16
+ arm_VCVT_CC_F64_FXU16
+ arm_VCVT_MI_F64_FXU16
+ arm_VCVT_PL_F64_FXU16
+ arm_VCVT_VS_F64_FXU16
+ arm_VCVT_VC_F64_FXU16
+ arm_VCVT_HI_F64_FXU16
+ arm_VCVT_LS_F64_FXU16
+ arm_VCVT_GE_F64_FXU16
+ arm_VCVT_LT_F64_FXU16
+ arm_VCVT_GT_F64_FXU16
+ arm_VCVT_LE_F64_FXU16
+ arm_VCVT_F64_FXU16
+ arm_VCVT_ZZ_F64_FXU16
+ arm_VCVT_EQ_F64_FXU32
+ arm_VCVT_NE_F64_FXU32
+ arm_VCVT_CS_F64_FXU32
+ arm_VCVT_CC_F64_FXU32
+ arm_VCVT_MI_F64_FXU32
+ arm_VCVT_PL_F64_FXU32
+ arm_VCVT_VS_F64_FXU32
+ arm_VCVT_VC_F64_FXU32
+ arm_VCVT_HI_F64_FXU32
+ arm_VCVT_LS_F64_FXU32
+ arm_VCVT_GE_F64_FXU32
+ arm_VCVT_LT_F64_FXU32
+ arm_VCVT_GT_F64_FXU32
+ arm_VCVT_LE_F64_FXU32
+ arm_VCVT_F64_FXU32
+ arm_VCVT_ZZ_F64_FXU32
+ arm_VCVT_EQ_F32_U32
+ arm_VCVT_NE_F32_U32
+ arm_VCVT_CS_F32_U32
+ arm_VCVT_CC_F32_U32
+ arm_VCVT_MI_F32_U32
+ arm_VCVT_PL_F32_U32
+ arm_VCVT_VS_F32_U32
+ arm_VCVT_VC_F32_U32
+ arm_VCVT_HI_F32_U32
+ arm_VCVT_LS_F32_U32
+ arm_VCVT_GE_F32_U32
+ arm_VCVT_LT_F32_U32
+ arm_VCVT_GT_F32_U32
+ arm_VCVT_LE_F32_U32
+ arm_VCVT_F32_U32
+ arm_VCVT_ZZ_F32_U32
+ arm_VCVT_EQ_F32_S32
+ arm_VCVT_NE_F32_S32
+ arm_VCVT_CS_F32_S32
+ arm_VCVT_CC_F32_S32
+ arm_VCVT_MI_F32_S32
+ arm_VCVT_PL_F32_S32
+ arm_VCVT_VS_F32_S32
+ arm_VCVT_VC_F32_S32
+ arm_VCVT_HI_F32_S32
+ arm_VCVT_LS_F32_S32
+ arm_VCVT_GE_F32_S32
+ arm_VCVT_LT_F32_S32
+ arm_VCVT_GT_F32_S32
+ arm_VCVT_LE_F32_S32
+ arm_VCVT_F32_S32
+ arm_VCVT_ZZ_F32_S32
+ arm_VCVT_EQ_F64_U32
+ arm_VCVT_NE_F64_U32
+ arm_VCVT_CS_F64_U32
+ arm_VCVT_CC_F64_U32
+ arm_VCVT_MI_F64_U32
+ arm_VCVT_PL_F64_U32
+ arm_VCVT_VS_F64_U32
+ arm_VCVT_VC_F64_U32
+ arm_VCVT_HI_F64_U32
+ arm_VCVT_LS_F64_U32
+ arm_VCVT_GE_F64_U32
+ arm_VCVT_LT_F64_U32
+ arm_VCVT_GT_F64_U32
+ arm_VCVT_LE_F64_U32
+ arm_VCVT_F64_U32
+ arm_VCVT_ZZ_F64_U32
+ arm_VCVT_EQ_F64_S32
+ arm_VCVT_NE_F64_S32
+ arm_VCVT_CS_F64_S32
+ arm_VCVT_CC_F64_S32
+ arm_VCVT_MI_F64_S32
+ arm_VCVT_PL_F64_S32
+ arm_VCVT_VS_F64_S32
+ arm_VCVT_VC_F64_S32
+ arm_VCVT_HI_F64_S32
+ arm_VCVT_LS_F64_S32
+ arm_VCVT_GE_F64_S32
+ arm_VCVT_LT_F64_S32
+ arm_VCVT_GT_F64_S32
+ arm_VCVT_LE_F64_S32
+ arm_VCVT_F64_S32
+ arm_VCVT_ZZ_F64_S32
+ arm_VCVT_EQ_F64_F32
+ arm_VCVT_NE_F64_F32
+ arm_VCVT_CS_F64_F32
+ arm_VCVT_CC_F64_F32
+ arm_VCVT_MI_F64_F32
+ arm_VCVT_PL_F64_F32
+ arm_VCVT_VS_F64_F32
+ arm_VCVT_VC_F64_F32
+ arm_VCVT_HI_F64_F32
+ arm_VCVT_LS_F64_F32
+ arm_VCVT_GE_F64_F32
+ arm_VCVT_LT_F64_F32
+ arm_VCVT_GT_F64_F32
+ arm_VCVT_LE_F64_F32
+ arm_VCVT_F64_F32
+ arm_VCVT_ZZ_F64_F32
+ arm_VCVT_EQ_F32_F64
+ arm_VCVT_NE_F32_F64
+ arm_VCVT_CS_F32_F64
+ arm_VCVT_CC_F32_F64
+ arm_VCVT_MI_F32_F64
+ arm_VCVT_PL_F32_F64
+ arm_VCVT_VS_F32_F64
+ arm_VCVT_VC_F32_F64
+ arm_VCVT_HI_F32_F64
+ arm_VCVT_LS_F32_F64
+ arm_VCVT_GE_F32_F64
+ arm_VCVT_LT_F32_F64
+ arm_VCVT_GT_F32_F64
+ arm_VCVT_LE_F32_F64
+ arm_VCVT_F32_F64
+ arm_VCVT_ZZ_F32_F64
+ arm_VCVT_EQ_FXS16_F32
+ arm_VCVT_NE_FXS16_F32
+ arm_VCVT_CS_FXS16_F32
+ arm_VCVT_CC_FXS16_F32
+ arm_VCVT_MI_FXS16_F32
+ arm_VCVT_PL_FXS16_F32
+ arm_VCVT_VS_FXS16_F32
+ arm_VCVT_VC_FXS16_F32
+ arm_VCVT_HI_FXS16_F32
+ arm_VCVT_LS_FXS16_F32
+ arm_VCVT_GE_FXS16_F32
+ arm_VCVT_LT_FXS16_F32
+ arm_VCVT_GT_FXS16_F32
+ arm_VCVT_LE_FXS16_F32
+ arm_VCVT_FXS16_F32
+ arm_VCVT_ZZ_FXS16_F32
+ arm_VCVT_EQ_FXS16_F64
+ arm_VCVT_NE_FXS16_F64
+ arm_VCVT_CS_FXS16_F64
+ arm_VCVT_CC_FXS16_F64
+ arm_VCVT_MI_FXS16_F64
+ arm_VCVT_PL_FXS16_F64
+ arm_VCVT_VS_FXS16_F64
+ arm_VCVT_VC_FXS16_F64
+ arm_VCVT_HI_FXS16_F64
+ arm_VCVT_LS_FXS16_F64
+ arm_VCVT_GE_FXS16_F64
+ arm_VCVT_LT_FXS16_F64
+ arm_VCVT_GT_FXS16_F64
+ arm_VCVT_LE_FXS16_F64
+ arm_VCVT_FXS16_F64
+ arm_VCVT_ZZ_FXS16_F64
+ arm_VCVT_EQ_FXS32_F32
+ arm_VCVT_NE_FXS32_F32
+ arm_VCVT_CS_FXS32_F32
+ arm_VCVT_CC_FXS32_F32
+ arm_VCVT_MI_FXS32_F32
+ arm_VCVT_PL_FXS32_F32
+ arm_VCVT_VS_FXS32_F32
+ arm_VCVT_VC_FXS32_F32
+ arm_VCVT_HI_FXS32_F32
+ arm_VCVT_LS_FXS32_F32
+ arm_VCVT_GE_FXS32_F32
+ arm_VCVT_LT_FXS32_F32
+ arm_VCVT_GT_FXS32_F32
+ arm_VCVT_LE_FXS32_F32
+ arm_VCVT_FXS32_F32
+ arm_VCVT_ZZ_FXS32_F32
+ arm_VCVT_EQ_FXS32_F64
+ arm_VCVT_NE_FXS32_F64
+ arm_VCVT_CS_FXS32_F64
+ arm_VCVT_CC_FXS32_F64
+ arm_VCVT_MI_FXS32_F64
+ arm_VCVT_PL_FXS32_F64
+ arm_VCVT_VS_FXS32_F64
+ arm_VCVT_VC_FXS32_F64
+ arm_VCVT_HI_FXS32_F64
+ arm_VCVT_LS_FXS32_F64
+ arm_VCVT_GE_FXS32_F64
+ arm_VCVT_LT_FXS32_F64
+ arm_VCVT_GT_FXS32_F64
+ arm_VCVT_LE_FXS32_F64
+ arm_VCVT_FXS32_F64
+ arm_VCVT_ZZ_FXS32_F64
+ arm_VCVT_EQ_FXU16_F32
+ arm_VCVT_NE_FXU16_F32
+ arm_VCVT_CS_FXU16_F32
+ arm_VCVT_CC_FXU16_F32
+ arm_VCVT_MI_FXU16_F32
+ arm_VCVT_PL_FXU16_F32
+ arm_VCVT_VS_FXU16_F32
+ arm_VCVT_VC_FXU16_F32
+ arm_VCVT_HI_FXU16_F32
+ arm_VCVT_LS_FXU16_F32
+ arm_VCVT_GE_FXU16_F32
+ arm_VCVT_LT_FXU16_F32
+ arm_VCVT_GT_FXU16_F32
+ arm_VCVT_LE_FXU16_F32
+ arm_VCVT_FXU16_F32
+ arm_VCVT_ZZ_FXU16_F32
+ arm_VCVT_EQ_FXU16_F64
+ arm_VCVT_NE_FXU16_F64
+ arm_VCVT_CS_FXU16_F64
+ arm_VCVT_CC_FXU16_F64
+ arm_VCVT_MI_FXU16_F64
+ arm_VCVT_PL_FXU16_F64
+ arm_VCVT_VS_FXU16_F64
+ arm_VCVT_VC_FXU16_F64
+ arm_VCVT_HI_FXU16_F64
+ arm_VCVT_LS_FXU16_F64
+ arm_VCVT_GE_FXU16_F64
+ arm_VCVT_LT_FXU16_F64
+ arm_VCVT_GT_FXU16_F64
+ arm_VCVT_LE_FXU16_F64
+ arm_VCVT_FXU16_F64
+ arm_VCVT_ZZ_FXU16_F64
+ arm_VCVT_EQ_FXU32_F32
+ arm_VCVT_NE_FXU32_F32
+ arm_VCVT_CS_FXU32_F32
+ arm_VCVT_CC_FXU32_F32
+ arm_VCVT_MI_FXU32_F32
+ arm_VCVT_PL_FXU32_F32
+ arm_VCVT_VS_FXU32_F32
+ arm_VCVT_VC_FXU32_F32
+ arm_VCVT_HI_FXU32_F32
+ arm_VCVT_LS_FXU32_F32
+ arm_VCVT_GE_FXU32_F32
+ arm_VCVT_LT_FXU32_F32
+ arm_VCVT_GT_FXU32_F32
+ arm_VCVT_LE_FXU32_F32
+ arm_VCVT_FXU32_F32
+ arm_VCVT_ZZ_FXU32_F32
+ arm_VCVT_EQ_FXU32_F64
+ arm_VCVT_NE_FXU32_F64
+ arm_VCVT_CS_FXU32_F64
+ arm_VCVT_CC_FXU32_F64
+ arm_VCVT_MI_FXU32_F64
+ arm_VCVT_PL_FXU32_F64
+ arm_VCVT_VS_FXU32_F64
+ arm_VCVT_VC_FXU32_F64
+ arm_VCVT_HI_FXU32_F64
+ arm_VCVT_LS_FXU32_F64
+ arm_VCVT_GE_FXU32_F64
+ arm_VCVT_LT_FXU32_F64
+ arm_VCVT_GT_FXU32_F64
+ arm_VCVT_LE_FXU32_F64
+ arm_VCVT_FXU32_F64
+ arm_VCVT_ZZ_FXU32_F64
+ arm_VCVTB_EQ_F32_F16
+ arm_VCVTB_NE_F32_F16
+ arm_VCVTB_CS_F32_F16
+ arm_VCVTB_CC_F32_F16
+ arm_VCVTB_MI_F32_F16
+ arm_VCVTB_PL_F32_F16
+ arm_VCVTB_VS_F32_F16
+ arm_VCVTB_VC_F32_F16
+ arm_VCVTB_HI_F32_F16
+ arm_VCVTB_LS_F32_F16
+ arm_VCVTB_GE_F32_F16
+ arm_VCVTB_LT_F32_F16
+ arm_VCVTB_GT_F32_F16
+ arm_VCVTB_LE_F32_F16
+ arm_VCVTB_F32_F16
+ arm_VCVTB_ZZ_F32_F16
+ arm_VCVTB_EQ_F16_F32
+ arm_VCVTB_NE_F16_F32
+ arm_VCVTB_CS_F16_F32
+ arm_VCVTB_CC_F16_F32
+ arm_VCVTB_MI_F16_F32
+ arm_VCVTB_PL_F16_F32
+ arm_VCVTB_VS_F16_F32
+ arm_VCVTB_VC_F16_F32
+ arm_VCVTB_HI_F16_F32
+ arm_VCVTB_LS_F16_F32
+ arm_VCVTB_GE_F16_F32
+ arm_VCVTB_LT_F16_F32
+ arm_VCVTB_GT_F16_F32
+ arm_VCVTB_LE_F16_F32
+ arm_VCVTB_F16_F32
+ arm_VCVTB_ZZ_F16_F32
+ arm_VCVTT_EQ_F32_F16
+ arm_VCVTT_NE_F32_F16
+ arm_VCVTT_CS_F32_F16
+ arm_VCVTT_CC_F32_F16
+ arm_VCVTT_MI_F32_F16
+ arm_VCVTT_PL_F32_F16
+ arm_VCVTT_VS_F32_F16
+ arm_VCVTT_VC_F32_F16
+ arm_VCVTT_HI_F32_F16
+ arm_VCVTT_LS_F32_F16
+ arm_VCVTT_GE_F32_F16
+ arm_VCVTT_LT_F32_F16
+ arm_VCVTT_GT_F32_F16
+ arm_VCVTT_LE_F32_F16
+ arm_VCVTT_F32_F16
+ arm_VCVTT_ZZ_F32_F16
+ arm_VCVTT_EQ_F16_F32
+ arm_VCVTT_NE_F16_F32
+ arm_VCVTT_CS_F16_F32
+ arm_VCVTT_CC_F16_F32
+ arm_VCVTT_MI_F16_F32
+ arm_VCVTT_PL_F16_F32
+ arm_VCVTT_VS_F16_F32
+ arm_VCVTT_VC_F16_F32
+ arm_VCVTT_HI_F16_F32
+ arm_VCVTT_LS_F16_F32
+ arm_VCVTT_GE_F16_F32
+ arm_VCVTT_LT_F16_F32
+ arm_VCVTT_GT_F16_F32
+ arm_VCVTT_LE_F16_F32
+ arm_VCVTT_F16_F32
+ arm_VCVTT_ZZ_F16_F32
+ arm_VCVTR_EQ_U32_F32
+ arm_VCVTR_NE_U32_F32
+ arm_VCVTR_CS_U32_F32
+ arm_VCVTR_CC_U32_F32
+ arm_VCVTR_MI_U32_F32
+ arm_VCVTR_PL_U32_F32
+ arm_VCVTR_VS_U32_F32
+ arm_VCVTR_VC_U32_F32
+ arm_VCVTR_HI_U32_F32
+ arm_VCVTR_LS_U32_F32
+ arm_VCVTR_GE_U32_F32
+ arm_VCVTR_LT_U32_F32
+ arm_VCVTR_GT_U32_F32
+ arm_VCVTR_LE_U32_F32
+ arm_VCVTR_U32_F32
+ arm_VCVTR_ZZ_U32_F32
+ arm_VCVTR_EQ_U32_F64
+ arm_VCVTR_NE_U32_F64
+ arm_VCVTR_CS_U32_F64
+ arm_VCVTR_CC_U32_F64
+ arm_VCVTR_MI_U32_F64
+ arm_VCVTR_PL_U32_F64
+ arm_VCVTR_VS_U32_F64
+ arm_VCVTR_VC_U32_F64
+ arm_VCVTR_HI_U32_F64
+ arm_VCVTR_LS_U32_F64
+ arm_VCVTR_GE_U32_F64
+ arm_VCVTR_LT_U32_F64
+ arm_VCVTR_GT_U32_F64
+ arm_VCVTR_LE_U32_F64
+ arm_VCVTR_U32_F64
+ arm_VCVTR_ZZ_U32_F64
+ arm_VCVTR_EQ_S32_F32
+ arm_VCVTR_NE_S32_F32
+ arm_VCVTR_CS_S32_F32
+ arm_VCVTR_CC_S32_F32
+ arm_VCVTR_MI_S32_F32
+ arm_VCVTR_PL_S32_F32
+ arm_VCVTR_VS_S32_F32
+ arm_VCVTR_VC_S32_F32
+ arm_VCVTR_HI_S32_F32
+ arm_VCVTR_LS_S32_F32
+ arm_VCVTR_GE_S32_F32
+ arm_VCVTR_LT_S32_F32
+ arm_VCVTR_GT_S32_F32
+ arm_VCVTR_LE_S32_F32
+ arm_VCVTR_S32_F32
+ arm_VCVTR_ZZ_S32_F32
+ arm_VCVTR_EQ_S32_F64
+ arm_VCVTR_NE_S32_F64
+ arm_VCVTR_CS_S32_F64
+ arm_VCVTR_CC_S32_F64
+ arm_VCVTR_MI_S32_F64
+ arm_VCVTR_PL_S32_F64
+ arm_VCVTR_VS_S32_F64
+ arm_VCVTR_VC_S32_F64
+ arm_VCVTR_HI_S32_F64
+ arm_VCVTR_LS_S32_F64
+ arm_VCVTR_GE_S32_F64
+ arm_VCVTR_LT_S32_F64
+ arm_VCVTR_GT_S32_F64
+ arm_VCVTR_LE_S32_F64
+ arm_VCVTR_S32_F64
+ arm_VCVTR_ZZ_S32_F64
+ arm_VCVT_EQ_U32_F32
+ arm_VCVT_NE_U32_F32
+ arm_VCVT_CS_U32_F32
+ arm_VCVT_CC_U32_F32
+ arm_VCVT_MI_U32_F32
+ arm_VCVT_PL_U32_F32
+ arm_VCVT_VS_U32_F32
+ arm_VCVT_VC_U32_F32
+ arm_VCVT_HI_U32_F32
+ arm_VCVT_LS_U32_F32
+ arm_VCVT_GE_U32_F32
+ arm_VCVT_LT_U32_F32
+ arm_VCVT_GT_U32_F32
+ arm_VCVT_LE_U32_F32
+ arm_VCVT_U32_F32
+ arm_VCVT_ZZ_U32_F32
+ arm_VCVT_EQ_U32_F64
+ arm_VCVT_NE_U32_F64
+ arm_VCVT_CS_U32_F64
+ arm_VCVT_CC_U32_F64
+ arm_VCVT_MI_U32_F64
+ arm_VCVT_PL_U32_F64
+ arm_VCVT_VS_U32_F64
+ arm_VCVT_VC_U32_F64
+ arm_VCVT_HI_U32_F64
+ arm_VCVT_LS_U32_F64
+ arm_VCVT_GE_U32_F64
+ arm_VCVT_LT_U32_F64
+ arm_VCVT_GT_U32_F64
+ arm_VCVT_LE_U32_F64
+ arm_VCVT_U32_F64
+ arm_VCVT_ZZ_U32_F64
+ arm_VCVT_EQ_S32_F32
+ arm_VCVT_NE_S32_F32
+ arm_VCVT_CS_S32_F32
+ arm_VCVT_CC_S32_F32
+ arm_VCVT_MI_S32_F32
+ arm_VCVT_PL_S32_F32
+ arm_VCVT_VS_S32_F32
+ arm_VCVT_VC_S32_F32
+ arm_VCVT_HI_S32_F32
+ arm_VCVT_LS_S32_F32
+ arm_VCVT_GE_S32_F32
+ arm_VCVT_LT_S32_F32
+ arm_VCVT_GT_S32_F32
+ arm_VCVT_LE_S32_F32
+ arm_VCVT_S32_F32
+ arm_VCVT_ZZ_S32_F32
+ arm_VCVT_EQ_S32_F64
+ arm_VCVT_NE_S32_F64
+ arm_VCVT_CS_S32_F64
+ arm_VCVT_CC_S32_F64
+ arm_VCVT_MI_S32_F64
+ arm_VCVT_PL_S32_F64
+ arm_VCVT_VS_S32_F64
+ arm_VCVT_VC_S32_F64
+ arm_VCVT_HI_S32_F64
+ arm_VCVT_LS_S32_F64
+ arm_VCVT_GE_S32_F64
+ arm_VCVT_LT_S32_F64
+ arm_VCVT_GT_S32_F64
+ arm_VCVT_LE_S32_F64
+ arm_VCVT_S32_F64
+ arm_VCVT_ZZ_S32_F64
+ arm_VDIV_EQ_F32
+ arm_VDIV_NE_F32
+ arm_VDIV_CS_F32
+ arm_VDIV_CC_F32
+ arm_VDIV_MI_F32
+ arm_VDIV_PL_F32
+ arm_VDIV_VS_F32
+ arm_VDIV_VC_F32
+ arm_VDIV_HI_F32
+ arm_VDIV_LS_F32
+ arm_VDIV_GE_F32
+ arm_VDIV_LT_F32
+ arm_VDIV_GT_F32
+ arm_VDIV_LE_F32
+ arm_VDIV_F32
+ arm_VDIV_ZZ_F32
+ arm_VDIV_EQ_F64
+ arm_VDIV_NE_F64
+ arm_VDIV_CS_F64
+ arm_VDIV_CC_F64
+ arm_VDIV_MI_F64
+ arm_VDIV_PL_F64
+ arm_VDIV_VS_F64
+ arm_VDIV_VC_F64
+ arm_VDIV_HI_F64
+ arm_VDIV_LS_F64
+ arm_VDIV_GE_F64
+ arm_VDIV_LT_F64
+ arm_VDIV_GT_F64
+ arm_VDIV_LE_F64
+ arm_VDIV_F64
+ arm_VDIV_ZZ_F64
+ arm_VLDR_EQ
+ arm_VLDR_NE
+ arm_VLDR_CS
+ arm_VLDR_CC
+ arm_VLDR_MI
+ arm_VLDR_PL
+ arm_VLDR_VS
+ arm_VLDR_VC
+ arm_VLDR_HI
+ arm_VLDR_LS
+ arm_VLDR_GE
+ arm_VLDR_LT
+ arm_VLDR_GT
+ arm_VLDR_LE
+ arm_VLDR
+ arm_VLDR_ZZ
+ arm_VMLA_EQ_F32
+ arm_VMLA_NE_F32
+ arm_VMLA_CS_F32
+ arm_VMLA_CC_F32
+ arm_VMLA_MI_F32
+ arm_VMLA_PL_F32
+ arm_VMLA_VS_F32
+ arm_VMLA_VC_F32
+ arm_VMLA_HI_F32
+ arm_VMLA_LS_F32
+ arm_VMLA_GE_F32
+ arm_VMLA_LT_F32
+ arm_VMLA_GT_F32
+ arm_VMLA_LE_F32
+ arm_VMLA_F32
+ arm_VMLA_ZZ_F32
+ arm_VMLA_EQ_F64
+ arm_VMLA_NE_F64
+ arm_VMLA_CS_F64
+ arm_VMLA_CC_F64
+ arm_VMLA_MI_F64
+ arm_VMLA_PL_F64
+ arm_VMLA_VS_F64
+ arm_VMLA_VC_F64
+ arm_VMLA_HI_F64
+ arm_VMLA_LS_F64
+ arm_VMLA_GE_F64
+ arm_VMLA_LT_F64
+ arm_VMLA_GT_F64
+ arm_VMLA_LE_F64
+ arm_VMLA_F64
+ arm_VMLA_ZZ_F64
+ arm_VMLS_EQ_F32
+ arm_VMLS_NE_F32
+ arm_VMLS_CS_F32
+ arm_VMLS_CC_F32
+ arm_VMLS_MI_F32
+ arm_VMLS_PL_F32
+ arm_VMLS_VS_F32
+ arm_VMLS_VC_F32
+ arm_VMLS_HI_F32
+ arm_VMLS_LS_F32
+ arm_VMLS_GE_F32
+ arm_VMLS_LT_F32
+ arm_VMLS_GT_F32
+ arm_VMLS_LE_F32
+ arm_VMLS_F32
+ arm_VMLS_ZZ_F32
+ arm_VMLS_EQ_F64
+ arm_VMLS_NE_F64
+ arm_VMLS_CS_F64
+ arm_VMLS_CC_F64
+ arm_VMLS_MI_F64
+ arm_VMLS_PL_F64
+ arm_VMLS_VS_F64
+ arm_VMLS_VC_F64
+ arm_VMLS_HI_F64
+ arm_VMLS_LS_F64
+ arm_VMLS_GE_F64
+ arm_VMLS_LT_F64
+ arm_VMLS_GT_F64
+ arm_VMLS_LE_F64
+ arm_VMLS_F64
+ arm_VMLS_ZZ_F64
+ arm_VMOV_EQ
+ arm_VMOV_NE
+ arm_VMOV_CS
+ arm_VMOV_CC
+ arm_VMOV_MI
+ arm_VMOV_PL
+ arm_VMOV_VS
+ arm_VMOV_VC
+ arm_VMOV_HI
+ arm_VMOV_LS
+ arm_VMOV_GE
+ arm_VMOV_LT
+ arm_VMOV_GT
+ arm_VMOV_LE
+ arm_VMOV
+ arm_VMOV_ZZ
+ arm_VMOV_EQ_32
+ arm_VMOV_NE_32
+ arm_VMOV_CS_32
+ arm_VMOV_CC_32
+ arm_VMOV_MI_32
+ arm_VMOV_PL_32
+ arm_VMOV_VS_32
+ arm_VMOV_VC_32
+ arm_VMOV_HI_32
+ arm_VMOV_LS_32
+ arm_VMOV_GE_32
+ arm_VMOV_LT_32
+ arm_VMOV_GT_32
+ arm_VMOV_LE_32
+ arm_VMOV_32
+ arm_VMOV_ZZ_32
+ arm_VMOV_EQ_F32
+ arm_VMOV_NE_F32
+ arm_VMOV_CS_F32
+ arm_VMOV_CC_F32
+ arm_VMOV_MI_F32
+ arm_VMOV_PL_F32
+ arm_VMOV_VS_F32
+ arm_VMOV_VC_F32
+ arm_VMOV_HI_F32
+ arm_VMOV_LS_F32
+ arm_VMOV_GE_F32
+ arm_VMOV_LT_F32
+ arm_VMOV_GT_F32
+ arm_VMOV_LE_F32
+ arm_VMOV_F32
+ arm_VMOV_ZZ_F32
+ arm_VMOV_EQ_F64
+ arm_VMOV_NE_F64
+ arm_VMOV_CS_F64
+ arm_VMOV_CC_F64
+ arm_VMOV_MI_F64
+ arm_VMOV_PL_F64
+ arm_VMOV_VS_F64
+ arm_VMOV_VC_F64
+ arm_VMOV_HI_F64
+ arm_VMOV_LS_F64
+ arm_VMOV_GE_F64
+ arm_VMOV_LT_F64
+ arm_VMOV_GT_F64
+ arm_VMOV_LE_F64
+ arm_VMOV_F64
+ arm_VMOV_ZZ_F64
+ arm_VMRS_EQ
+ arm_VMRS_NE
+ arm_VMRS_CS
+ arm_VMRS_CC
+ arm_VMRS_MI
+ arm_VMRS_PL
+ arm_VMRS_VS
+ arm_VMRS_VC
+ arm_VMRS_HI
+ arm_VMRS_LS
+ arm_VMRS_GE
+ arm_VMRS_LT
+ arm_VMRS_GT
+ arm_VMRS_LE
+ arm_VMRS
+ arm_VMRS_ZZ
+ arm_VMSR_EQ
+ arm_VMSR_NE
+ arm_VMSR_CS
+ arm_VMSR_CC
+ arm_VMSR_MI
+ arm_VMSR_PL
+ arm_VMSR_VS
+ arm_VMSR_VC
+ arm_VMSR_HI
+ arm_VMSR_LS
+ arm_VMSR_GE
+ arm_VMSR_LT
+ arm_VMSR_GT
+ arm_VMSR_LE
+ arm_VMSR
+ arm_VMSR_ZZ
+ arm_VMUL_EQ_F32
+ arm_VMUL_NE_F32
+ arm_VMUL_CS_F32
+ arm_VMUL_CC_F32
+ arm_VMUL_MI_F32
+ arm_VMUL_PL_F32
+ arm_VMUL_VS_F32
+ arm_VMUL_VC_F32
+ arm_VMUL_HI_F32
+ arm_VMUL_LS_F32
+ arm_VMUL_GE_F32
+ arm_VMUL_LT_F32
+ arm_VMUL_GT_F32
+ arm_VMUL_LE_F32
+ arm_VMUL_F32
+ arm_VMUL_ZZ_F32
+ arm_VMUL_EQ_F64
+ arm_VMUL_NE_F64
+ arm_VMUL_CS_F64
+ arm_VMUL_CC_F64
+ arm_VMUL_MI_F64
+ arm_VMUL_PL_F64
+ arm_VMUL_VS_F64
+ arm_VMUL_VC_F64
+ arm_VMUL_HI_F64
+ arm_VMUL_LS_F64
+ arm_VMUL_GE_F64
+ arm_VMUL_LT_F64
+ arm_VMUL_GT_F64
+ arm_VMUL_LE_F64
+ arm_VMUL_F64
+ arm_VMUL_ZZ_F64
+ arm_VNEG_EQ_F32
+ arm_VNEG_NE_F32
+ arm_VNEG_CS_F32
+ arm_VNEG_CC_F32
+ arm_VNEG_MI_F32
+ arm_VNEG_PL_F32
+ arm_VNEG_VS_F32
+ arm_VNEG_VC_F32
+ arm_VNEG_HI_F32
+ arm_VNEG_LS_F32
+ arm_VNEG_GE_F32
+ arm_VNEG_LT_F32
+ arm_VNEG_GT_F32
+ arm_VNEG_LE_F32
+ arm_VNEG_F32
+ arm_VNEG_ZZ_F32
+ arm_VNEG_EQ_F64
+ arm_VNEG_NE_F64
+ arm_VNEG_CS_F64
+ arm_VNEG_CC_F64
+ arm_VNEG_MI_F64
+ arm_VNEG_PL_F64
+ arm_VNEG_VS_F64
+ arm_VNEG_VC_F64
+ arm_VNEG_HI_F64
+ arm_VNEG_LS_F64
+ arm_VNEG_GE_F64
+ arm_VNEG_LT_F64
+ arm_VNEG_GT_F64
+ arm_VNEG_LE_F64
+ arm_VNEG_F64
+ arm_VNEG_ZZ_F64
+ arm_VNMLS_EQ_F32
+ arm_VNMLS_NE_F32
+ arm_VNMLS_CS_F32
+ arm_VNMLS_CC_F32
+ arm_VNMLS_MI_F32
+ arm_VNMLS_PL_F32
+ arm_VNMLS_VS_F32
+ arm_VNMLS_VC_F32
+ arm_VNMLS_HI_F32
+ arm_VNMLS_LS_F32
+ arm_VNMLS_GE_F32
+ arm_VNMLS_LT_F32
+ arm_VNMLS_GT_F32
+ arm_VNMLS_LE_F32
+ arm_VNMLS_F32
+ arm_VNMLS_ZZ_F32
+ arm_VNMLS_EQ_F64
+ arm_VNMLS_NE_F64
+ arm_VNMLS_CS_F64
+ arm_VNMLS_CC_F64
+ arm_VNMLS_MI_F64
+ arm_VNMLS_PL_F64
+ arm_VNMLS_VS_F64
+ arm_VNMLS_VC_F64
+ arm_VNMLS_HI_F64
+ arm_VNMLS_LS_F64
+ arm_VNMLS_GE_F64
+ arm_VNMLS_LT_F64
+ arm_VNMLS_GT_F64
+ arm_VNMLS_LE_F64
+ arm_VNMLS_F64
+ arm_VNMLS_ZZ_F64
+ arm_VNMLA_EQ_F32
+ arm_VNMLA_NE_F32
+ arm_VNMLA_CS_F32
+ arm_VNMLA_CC_F32
+ arm_VNMLA_MI_F32
+ arm_VNMLA_PL_F32
+ arm_VNMLA_VS_F32
+ arm_VNMLA_VC_F32
+ arm_VNMLA_HI_F32
+ arm_VNMLA_LS_F32
+ arm_VNMLA_GE_F32
+ arm_VNMLA_LT_F32
+ arm_VNMLA_GT_F32
+ arm_VNMLA_LE_F32
+ arm_VNMLA_F32
+ arm_VNMLA_ZZ_F32
+ arm_VNMLA_EQ_F64
+ arm_VNMLA_NE_F64
+ arm_VNMLA_CS_F64
+ arm_VNMLA_CC_F64
+ arm_VNMLA_MI_F64
+ arm_VNMLA_PL_F64
+ arm_VNMLA_VS_F64
+ arm_VNMLA_VC_F64
+ arm_VNMLA_HI_F64
+ arm_VNMLA_LS_F64
+ arm_VNMLA_GE_F64
+ arm_VNMLA_LT_F64
+ arm_VNMLA_GT_F64
+ arm_VNMLA_LE_F64
+ arm_VNMLA_F64
+ arm_VNMLA_ZZ_F64
+ arm_VNMUL_EQ_F32
+ arm_VNMUL_NE_F32
+ arm_VNMUL_CS_F32
+ arm_VNMUL_CC_F32
+ arm_VNMUL_MI_F32
+ arm_VNMUL_PL_F32
+ arm_VNMUL_VS_F32
+ arm_VNMUL_VC_F32
+ arm_VNMUL_HI_F32
+ arm_VNMUL_LS_F32
+ arm_VNMUL_GE_F32
+ arm_VNMUL_LT_F32
+ arm_VNMUL_GT_F32
+ arm_VNMUL_LE_F32
+ arm_VNMUL_F32
+ arm_VNMUL_ZZ_F32
+ arm_VNMUL_EQ_F64
+ arm_VNMUL_NE_F64
+ arm_VNMUL_CS_F64
+ arm_VNMUL_CC_F64
+ arm_VNMUL_MI_F64
+ arm_VNMUL_PL_F64
+ arm_VNMUL_VS_F64
+ arm_VNMUL_VC_F64
+ arm_VNMUL_HI_F64
+ arm_VNMUL_LS_F64
+ arm_VNMUL_GE_F64
+ arm_VNMUL_LT_F64
+ arm_VNMUL_GT_F64
+ arm_VNMUL_LE_F64
+ arm_VNMUL_F64
+ arm_VNMUL_ZZ_F64
+ arm_VSQRT_EQ_F32
+ arm_VSQRT_NE_F32
+ arm_VSQRT_CS_F32
+ arm_VSQRT_CC_F32
+ arm_VSQRT_MI_F32
+ arm_VSQRT_PL_F32
+ arm_VSQRT_VS_F32
+ arm_VSQRT_VC_F32
+ arm_VSQRT_HI_F32
+ arm_VSQRT_LS_F32
+ arm_VSQRT_GE_F32
+ arm_VSQRT_LT_F32
+ arm_VSQRT_GT_F32
+ arm_VSQRT_LE_F32
+ arm_VSQRT_F32
+ arm_VSQRT_ZZ_F32
+ arm_VSQRT_EQ_F64
+ arm_VSQRT_NE_F64
+ arm_VSQRT_CS_F64
+ arm_VSQRT_CC_F64
+ arm_VSQRT_MI_F64
+ arm_VSQRT_PL_F64
+ arm_VSQRT_VS_F64
+ arm_VSQRT_VC_F64
+ arm_VSQRT_HI_F64
+ arm_VSQRT_LS_F64
+ arm_VSQRT_GE_F64
+ arm_VSQRT_LT_F64
+ arm_VSQRT_GT_F64
+ arm_VSQRT_LE_F64
+ arm_VSQRT_F64
+ arm_VSQRT_ZZ_F64
+ arm_VSTR_EQ
+ arm_VSTR_NE
+ arm_VSTR_CS
+ arm_VSTR_CC
+ arm_VSTR_MI
+ arm_VSTR_PL
+ arm_VSTR_VS
+ arm_VSTR_VC
+ arm_VSTR_HI
+ arm_VSTR_LS
+ arm_VSTR_GE
+ arm_VSTR_LT
+ arm_VSTR_GT
+ arm_VSTR_LE
+ arm_VSTR
+ arm_VSTR_ZZ
+ arm_VSUB_EQ_F32
+ arm_VSUB_NE_F32
+ arm_VSUB_CS_F32
+ arm_VSUB_CC_F32
+ arm_VSUB_MI_F32
+ arm_VSUB_PL_F32
+ arm_VSUB_VS_F32
+ arm_VSUB_VC_F32
+ arm_VSUB_HI_F32
+ arm_VSUB_LS_F32
+ arm_VSUB_GE_F32
+ arm_VSUB_LT_F32
+ arm_VSUB_GT_F32
+ arm_VSUB_LE_F32
+ arm_VSUB_F32
+ arm_VSUB_ZZ_F32
+ arm_VSUB_EQ_F64
+ arm_VSUB_NE_F64
+ arm_VSUB_CS_F64
+ arm_VSUB_CC_F64
+ arm_VSUB_MI_F64
+ arm_VSUB_PL_F64
+ arm_VSUB_VS_F64
+ arm_VSUB_VC_F64
+ arm_VSUB_HI_F64
+ arm_VSUB_LS_F64
+ arm_VSUB_GE_F64
+ arm_VSUB_LT_F64
+ arm_VSUB_GT_F64
+ arm_VSUB_LE_F64
+ arm_VSUB_F64
+ arm_VSUB_ZZ_F64
+ arm_WFE_EQ
+ arm_WFE_NE
+ arm_WFE_CS
+ arm_WFE_CC
+ arm_WFE_MI
+ arm_WFE_PL
+ arm_WFE_VS
+ arm_WFE_VC
+ arm_WFE_HI
+ arm_WFE_LS
+ arm_WFE_GE
+ arm_WFE_LT
+ arm_WFE_GT
+ arm_WFE_LE
+ arm_WFE
+ arm_WFE_ZZ
+ arm_WFI_EQ
+ arm_WFI_NE
+ arm_WFI_CS
+ arm_WFI_CC
+ arm_WFI_MI
+ arm_WFI_PL
+ arm_WFI_VS
+ arm_WFI_VC
+ arm_WFI_HI
+ arm_WFI_LS
+ arm_WFI_GE
+ arm_WFI_LT
+ arm_WFI_GT
+ arm_WFI_LE
+ arm_WFI
+ arm_WFI_ZZ
+ arm_YIELD_EQ
+ arm_YIELD_NE
+ arm_YIELD_CS
+ arm_YIELD_CC
+ arm_YIELD_MI
+ arm_YIELD_PL
+ arm_YIELD_VS
+ arm_YIELD_VC
+ arm_YIELD_HI
+ arm_YIELD_LS
+ arm_YIELD_GE
+ arm_YIELD_LT
+ arm_YIELD_GT
+ arm_YIELD_LE
+ arm_YIELD
+ arm_YIELD_ZZ
+)
+
+var arm_opstr = [...]string{
+ arm_ADC_EQ: "ADC.EQ",
+ arm_ADC_NE: "ADC.NE",
+ arm_ADC_CS: "ADC.CS",
+ arm_ADC_CC: "ADC.CC",
+ arm_ADC_MI: "ADC.MI",
+ arm_ADC_PL: "ADC.PL",
+ arm_ADC_VS: "ADC.VS",
+ arm_ADC_VC: "ADC.VC",
+ arm_ADC_HI: "ADC.HI",
+ arm_ADC_LS: "ADC.LS",
+ arm_ADC_GE: "ADC.GE",
+ arm_ADC_LT: "ADC.LT",
+ arm_ADC_GT: "ADC.GT",
+ arm_ADC_LE: "ADC.LE",
+ arm_ADC: "ADC",
+ arm_ADC_ZZ: "ADC.ZZ",
+ arm_ADC_S_EQ: "ADC.S.EQ",
+ arm_ADC_S_NE: "ADC.S.NE",
+ arm_ADC_S_CS: "ADC.S.CS",
+ arm_ADC_S_CC: "ADC.S.CC",
+ arm_ADC_S_MI: "ADC.S.MI",
+ arm_ADC_S_PL: "ADC.S.PL",
+ arm_ADC_S_VS: "ADC.S.VS",
+ arm_ADC_S_VC: "ADC.S.VC",
+ arm_ADC_S_HI: "ADC.S.HI",
+ arm_ADC_S_LS: "ADC.S.LS",
+ arm_ADC_S_GE: "ADC.S.GE",
+ arm_ADC_S_LT: "ADC.S.LT",
+ arm_ADC_S_GT: "ADC.S.GT",
+ arm_ADC_S_LE: "ADC.S.LE",
+ arm_ADC_S: "ADC.S",
+ arm_ADC_S_ZZ: "ADC.S.ZZ",
+ arm_ADD_EQ: "ADD.EQ",
+ arm_ADD_NE: "ADD.NE",
+ arm_ADD_CS: "ADD.CS",
+ arm_ADD_CC: "ADD.CC",
+ arm_ADD_MI: "ADD.MI",
+ arm_ADD_PL: "ADD.PL",
+ arm_ADD_VS: "ADD.VS",
+ arm_ADD_VC: "ADD.VC",
+ arm_ADD_HI: "ADD.HI",
+ arm_ADD_LS: "ADD.LS",
+ arm_ADD_GE: "ADD.GE",
+ arm_ADD_LT: "ADD.LT",
+ arm_ADD_GT: "ADD.GT",
+ arm_ADD_LE: "ADD.LE",
+ arm_ADD: "ADD",
+ arm_ADD_ZZ: "ADD.ZZ",
+ arm_ADD_S_EQ: "ADD.S.EQ",
+ arm_ADD_S_NE: "ADD.S.NE",
+ arm_ADD_S_CS: "ADD.S.CS",
+ arm_ADD_S_CC: "ADD.S.CC",
+ arm_ADD_S_MI: "ADD.S.MI",
+ arm_ADD_S_PL: "ADD.S.PL",
+ arm_ADD_S_VS: "ADD.S.VS",
+ arm_ADD_S_VC: "ADD.S.VC",
+ arm_ADD_S_HI: "ADD.S.HI",
+ arm_ADD_S_LS: "ADD.S.LS",
+ arm_ADD_S_GE: "ADD.S.GE",
+ arm_ADD_S_LT: "ADD.S.LT",
+ arm_ADD_S_GT: "ADD.S.GT",
+ arm_ADD_S_LE: "ADD.S.LE",
+ arm_ADD_S: "ADD.S",
+ arm_ADD_S_ZZ: "ADD.S.ZZ",
+ arm_AND_EQ: "AND.EQ",
+ arm_AND_NE: "AND.NE",
+ arm_AND_CS: "AND.CS",
+ arm_AND_CC: "AND.CC",
+ arm_AND_MI: "AND.MI",
+ arm_AND_PL: "AND.PL",
+ arm_AND_VS: "AND.VS",
+ arm_AND_VC: "AND.VC",
+ arm_AND_HI: "AND.HI",
+ arm_AND_LS: "AND.LS",
+ arm_AND_GE: "AND.GE",
+ arm_AND_LT: "AND.LT",
+ arm_AND_GT: "AND.GT",
+ arm_AND_LE: "AND.LE",
+ arm_AND: "AND",
+ arm_AND_ZZ: "AND.ZZ",
+ arm_AND_S_EQ: "AND.S.EQ",
+ arm_AND_S_NE: "AND.S.NE",
+ arm_AND_S_CS: "AND.S.CS",
+ arm_AND_S_CC: "AND.S.CC",
+ arm_AND_S_MI: "AND.S.MI",
+ arm_AND_S_PL: "AND.S.PL",
+ arm_AND_S_VS: "AND.S.VS",
+ arm_AND_S_VC: "AND.S.VC",
+ arm_AND_S_HI: "AND.S.HI",
+ arm_AND_S_LS: "AND.S.LS",
+ arm_AND_S_GE: "AND.S.GE",
+ arm_AND_S_LT: "AND.S.LT",
+ arm_AND_S_GT: "AND.S.GT",
+ arm_AND_S_LE: "AND.S.LE",
+ arm_AND_S: "AND.S",
+ arm_AND_S_ZZ: "AND.S.ZZ",
+ arm_ASR_EQ: "ASR.EQ",
+ arm_ASR_NE: "ASR.NE",
+ arm_ASR_CS: "ASR.CS",
+ arm_ASR_CC: "ASR.CC",
+ arm_ASR_MI: "ASR.MI",
+ arm_ASR_PL: "ASR.PL",
+ arm_ASR_VS: "ASR.VS",
+ arm_ASR_VC: "ASR.VC",
+ arm_ASR_HI: "ASR.HI",
+ arm_ASR_LS: "ASR.LS",
+ arm_ASR_GE: "ASR.GE",
+ arm_ASR_LT: "ASR.LT",
+ arm_ASR_GT: "ASR.GT",
+ arm_ASR_LE: "ASR.LE",
+ arm_ASR: "ASR",
+ arm_ASR_ZZ: "ASR.ZZ",
+ arm_ASR_S_EQ: "ASR.S.EQ",
+ arm_ASR_S_NE: "ASR.S.NE",
+ arm_ASR_S_CS: "ASR.S.CS",
+ arm_ASR_S_CC: "ASR.S.CC",
+ arm_ASR_S_MI: "ASR.S.MI",
+ arm_ASR_S_PL: "ASR.S.PL",
+ arm_ASR_S_VS: "ASR.S.VS",
+ arm_ASR_S_VC: "ASR.S.VC",
+ arm_ASR_S_HI: "ASR.S.HI",
+ arm_ASR_S_LS: "ASR.S.LS",
+ arm_ASR_S_GE: "ASR.S.GE",
+ arm_ASR_S_LT: "ASR.S.LT",
+ arm_ASR_S_GT: "ASR.S.GT",
+ arm_ASR_S_LE: "ASR.S.LE",
+ arm_ASR_S: "ASR.S",
+ arm_ASR_S_ZZ: "ASR.S.ZZ",
+ arm_B_EQ: "B.EQ",
+ arm_B_NE: "B.NE",
+ arm_B_CS: "B.CS",
+ arm_B_CC: "B.CC",
+ arm_B_MI: "B.MI",
+ arm_B_PL: "B.PL",
+ arm_B_VS: "B.VS",
+ arm_B_VC: "B.VC",
+ arm_B_HI: "B.HI",
+ arm_B_LS: "B.LS",
+ arm_B_GE: "B.GE",
+ arm_B_LT: "B.LT",
+ arm_B_GT: "B.GT",
+ arm_B_LE: "B.LE",
+ arm_B: "B",
+ arm_B_ZZ: "B.ZZ",
+ arm_BFC_EQ: "BFC.EQ",
+ arm_BFC_NE: "BFC.NE",
+ arm_BFC_CS: "BFC.CS",
+ arm_BFC_CC: "BFC.CC",
+ arm_BFC_MI: "BFC.MI",
+ arm_BFC_PL: "BFC.PL",
+ arm_BFC_VS: "BFC.VS",
+ arm_BFC_VC: "BFC.VC",
+ arm_BFC_HI: "BFC.HI",
+ arm_BFC_LS: "BFC.LS",
+ arm_BFC_GE: "BFC.GE",
+ arm_BFC_LT: "BFC.LT",
+ arm_BFC_GT: "BFC.GT",
+ arm_BFC_LE: "BFC.LE",
+ arm_BFC: "BFC",
+ arm_BFC_ZZ: "BFC.ZZ",
+ arm_BFI_EQ: "BFI.EQ",
+ arm_BFI_NE: "BFI.NE",
+ arm_BFI_CS: "BFI.CS",
+ arm_BFI_CC: "BFI.CC",
+ arm_BFI_MI: "BFI.MI",
+ arm_BFI_PL: "BFI.PL",
+ arm_BFI_VS: "BFI.VS",
+ arm_BFI_VC: "BFI.VC",
+ arm_BFI_HI: "BFI.HI",
+ arm_BFI_LS: "BFI.LS",
+ arm_BFI_GE: "BFI.GE",
+ arm_BFI_LT: "BFI.LT",
+ arm_BFI_GT: "BFI.GT",
+ arm_BFI_LE: "BFI.LE",
+ arm_BFI: "BFI",
+ arm_BFI_ZZ: "BFI.ZZ",
+ arm_BIC_EQ: "BIC.EQ",
+ arm_BIC_NE: "BIC.NE",
+ arm_BIC_CS: "BIC.CS",
+ arm_BIC_CC: "BIC.CC",
+ arm_BIC_MI: "BIC.MI",
+ arm_BIC_PL: "BIC.PL",
+ arm_BIC_VS: "BIC.VS",
+ arm_BIC_VC: "BIC.VC",
+ arm_BIC_HI: "BIC.HI",
+ arm_BIC_LS: "BIC.LS",
+ arm_BIC_GE: "BIC.GE",
+ arm_BIC_LT: "BIC.LT",
+ arm_BIC_GT: "BIC.GT",
+ arm_BIC_LE: "BIC.LE",
+ arm_BIC: "BIC",
+ arm_BIC_ZZ: "BIC.ZZ",
+ arm_BIC_S_EQ: "BIC.S.EQ",
+ arm_BIC_S_NE: "BIC.S.NE",
+ arm_BIC_S_CS: "BIC.S.CS",
+ arm_BIC_S_CC: "BIC.S.CC",
+ arm_BIC_S_MI: "BIC.S.MI",
+ arm_BIC_S_PL: "BIC.S.PL",
+ arm_BIC_S_VS: "BIC.S.VS",
+ arm_BIC_S_VC: "BIC.S.VC",
+ arm_BIC_S_HI: "BIC.S.HI",
+ arm_BIC_S_LS: "BIC.S.LS",
+ arm_BIC_S_GE: "BIC.S.GE",
+ arm_BIC_S_LT: "BIC.S.LT",
+ arm_BIC_S_GT: "BIC.S.GT",
+ arm_BIC_S_LE: "BIC.S.LE",
+ arm_BIC_S: "BIC.S",
+ arm_BIC_S_ZZ: "BIC.S.ZZ",
+ arm_BKPT_EQ: "BKPT.EQ",
+ arm_BKPT_NE: "BKPT.NE",
+ arm_BKPT_CS: "BKPT.CS",
+ arm_BKPT_CC: "BKPT.CC",
+ arm_BKPT_MI: "BKPT.MI",
+ arm_BKPT_PL: "BKPT.PL",
+ arm_BKPT_VS: "BKPT.VS",
+ arm_BKPT_VC: "BKPT.VC",
+ arm_BKPT_HI: "BKPT.HI",
+ arm_BKPT_LS: "BKPT.LS",
+ arm_BKPT_GE: "BKPT.GE",
+ arm_BKPT_LT: "BKPT.LT",
+ arm_BKPT_GT: "BKPT.GT",
+ arm_BKPT_LE: "BKPT.LE",
+ arm_BKPT: "BKPT",
+ arm_BKPT_ZZ: "BKPT.ZZ",
+ arm_BL_EQ: "BL.EQ",
+ arm_BL_NE: "BL.NE",
+ arm_BL_CS: "BL.CS",
+ arm_BL_CC: "BL.CC",
+ arm_BL_MI: "BL.MI",
+ arm_BL_PL: "BL.PL",
+ arm_BL_VS: "BL.VS",
+ arm_BL_VC: "BL.VC",
+ arm_BL_HI: "BL.HI",
+ arm_BL_LS: "BL.LS",
+ arm_BL_GE: "BL.GE",
+ arm_BL_LT: "BL.LT",
+ arm_BL_GT: "BL.GT",
+ arm_BL_LE: "BL.LE",
+ arm_BL: "BL",
+ arm_BL_ZZ: "BL.ZZ",
+ arm_BLX_EQ: "BLX.EQ",
+ arm_BLX_NE: "BLX.NE",
+ arm_BLX_CS: "BLX.CS",
+ arm_BLX_CC: "BLX.CC",
+ arm_BLX_MI: "BLX.MI",
+ arm_BLX_PL: "BLX.PL",
+ arm_BLX_VS: "BLX.VS",
+ arm_BLX_VC: "BLX.VC",
+ arm_BLX_HI: "BLX.HI",
+ arm_BLX_LS: "BLX.LS",
+ arm_BLX_GE: "BLX.GE",
+ arm_BLX_LT: "BLX.LT",
+ arm_BLX_GT: "BLX.GT",
+ arm_BLX_LE: "BLX.LE",
+ arm_BLX: "BLX",
+ arm_BLX_ZZ: "BLX.ZZ",
+ arm_BX_EQ: "BX.EQ",
+ arm_BX_NE: "BX.NE",
+ arm_BX_CS: "BX.CS",
+ arm_BX_CC: "BX.CC",
+ arm_BX_MI: "BX.MI",
+ arm_BX_PL: "BX.PL",
+ arm_BX_VS: "BX.VS",
+ arm_BX_VC: "BX.VC",
+ arm_BX_HI: "BX.HI",
+ arm_BX_LS: "BX.LS",
+ arm_BX_GE: "BX.GE",
+ arm_BX_LT: "BX.LT",
+ arm_BX_GT: "BX.GT",
+ arm_BX_LE: "BX.LE",
+ arm_BX: "BX",
+ arm_BX_ZZ: "BX.ZZ",
+ arm_BXJ_EQ: "BXJ.EQ",
+ arm_BXJ_NE: "BXJ.NE",
+ arm_BXJ_CS: "BXJ.CS",
+ arm_BXJ_CC: "BXJ.CC",
+ arm_BXJ_MI: "BXJ.MI",
+ arm_BXJ_PL: "BXJ.PL",
+ arm_BXJ_VS: "BXJ.VS",
+ arm_BXJ_VC: "BXJ.VC",
+ arm_BXJ_HI: "BXJ.HI",
+ arm_BXJ_LS: "BXJ.LS",
+ arm_BXJ_GE: "BXJ.GE",
+ arm_BXJ_LT: "BXJ.LT",
+ arm_BXJ_GT: "BXJ.GT",
+ arm_BXJ_LE: "BXJ.LE",
+ arm_BXJ: "BXJ",
+ arm_BXJ_ZZ: "BXJ.ZZ",
+ arm_CLREX: "CLREX",
+ arm_CLZ_EQ: "CLZ.EQ",
+ arm_CLZ_NE: "CLZ.NE",
+ arm_CLZ_CS: "CLZ.CS",
+ arm_CLZ_CC: "CLZ.CC",
+ arm_CLZ_MI: "CLZ.MI",
+ arm_CLZ_PL: "CLZ.PL",
+ arm_CLZ_VS: "CLZ.VS",
+ arm_CLZ_VC: "CLZ.VC",
+ arm_CLZ_HI: "CLZ.HI",
+ arm_CLZ_LS: "CLZ.LS",
+ arm_CLZ_GE: "CLZ.GE",
+ arm_CLZ_LT: "CLZ.LT",
+ arm_CLZ_GT: "CLZ.GT",
+ arm_CLZ_LE: "CLZ.LE",
+ arm_CLZ: "CLZ",
+ arm_CLZ_ZZ: "CLZ.ZZ",
+ arm_CMN_EQ: "CMN.EQ",
+ arm_CMN_NE: "CMN.NE",
+ arm_CMN_CS: "CMN.CS",
+ arm_CMN_CC: "CMN.CC",
+ arm_CMN_MI: "CMN.MI",
+ arm_CMN_PL: "CMN.PL",
+ arm_CMN_VS: "CMN.VS",
+ arm_CMN_VC: "CMN.VC",
+ arm_CMN_HI: "CMN.HI",
+ arm_CMN_LS: "CMN.LS",
+ arm_CMN_GE: "CMN.GE",
+ arm_CMN_LT: "CMN.LT",
+ arm_CMN_GT: "CMN.GT",
+ arm_CMN_LE: "CMN.LE",
+ arm_CMN: "CMN",
+ arm_CMN_ZZ: "CMN.ZZ",
+ arm_CMP_EQ: "CMP.EQ",
+ arm_CMP_NE: "CMP.NE",
+ arm_CMP_CS: "CMP.CS",
+ arm_CMP_CC: "CMP.CC",
+ arm_CMP_MI: "CMP.MI",
+ arm_CMP_PL: "CMP.PL",
+ arm_CMP_VS: "CMP.VS",
+ arm_CMP_VC: "CMP.VC",
+ arm_CMP_HI: "CMP.HI",
+ arm_CMP_LS: "CMP.LS",
+ arm_CMP_GE: "CMP.GE",
+ arm_CMP_LT: "CMP.LT",
+ arm_CMP_GT: "CMP.GT",
+ arm_CMP_LE: "CMP.LE",
+ arm_CMP: "CMP",
+ arm_CMP_ZZ: "CMP.ZZ",
+ arm_DBG_EQ: "DBG.EQ",
+ arm_DBG_NE: "DBG.NE",
+ arm_DBG_CS: "DBG.CS",
+ arm_DBG_CC: "DBG.CC",
+ arm_DBG_MI: "DBG.MI",
+ arm_DBG_PL: "DBG.PL",
+ arm_DBG_VS: "DBG.VS",
+ arm_DBG_VC: "DBG.VC",
+ arm_DBG_HI: "DBG.HI",
+ arm_DBG_LS: "DBG.LS",
+ arm_DBG_GE: "DBG.GE",
+ arm_DBG_LT: "DBG.LT",
+ arm_DBG_GT: "DBG.GT",
+ arm_DBG_LE: "DBG.LE",
+ arm_DBG: "DBG",
+ arm_DBG_ZZ: "DBG.ZZ",
+ arm_DMB: "DMB",
+ arm_DSB: "DSB",
+ arm_EOR_EQ: "EOR.EQ",
+ arm_EOR_NE: "EOR.NE",
+ arm_EOR_CS: "EOR.CS",
+ arm_EOR_CC: "EOR.CC",
+ arm_EOR_MI: "EOR.MI",
+ arm_EOR_PL: "EOR.PL",
+ arm_EOR_VS: "EOR.VS",
+ arm_EOR_VC: "EOR.VC",
+ arm_EOR_HI: "EOR.HI",
+ arm_EOR_LS: "EOR.LS",
+ arm_EOR_GE: "EOR.GE",
+ arm_EOR_LT: "EOR.LT",
+ arm_EOR_GT: "EOR.GT",
+ arm_EOR_LE: "EOR.LE",
+ arm_EOR: "EOR",
+ arm_EOR_ZZ: "EOR.ZZ",
+ arm_EOR_S_EQ: "EOR.S.EQ",
+ arm_EOR_S_NE: "EOR.S.NE",
+ arm_EOR_S_CS: "EOR.S.CS",
+ arm_EOR_S_CC: "EOR.S.CC",
+ arm_EOR_S_MI: "EOR.S.MI",
+ arm_EOR_S_PL: "EOR.S.PL",
+ arm_EOR_S_VS: "EOR.S.VS",
+ arm_EOR_S_VC: "EOR.S.VC",
+ arm_EOR_S_HI: "EOR.S.HI",
+ arm_EOR_S_LS: "EOR.S.LS",
+ arm_EOR_S_GE: "EOR.S.GE",
+ arm_EOR_S_LT: "EOR.S.LT",
+ arm_EOR_S_GT: "EOR.S.GT",
+ arm_EOR_S_LE: "EOR.S.LE",
+ arm_EOR_S: "EOR.S",
+ arm_EOR_S_ZZ: "EOR.S.ZZ",
+ arm_ISB: "ISB",
+ arm_LDM_EQ: "LDM.EQ",
+ arm_LDM_NE: "LDM.NE",
+ arm_LDM_CS: "LDM.CS",
+ arm_LDM_CC: "LDM.CC",
+ arm_LDM_MI: "LDM.MI",
+ arm_LDM_PL: "LDM.PL",
+ arm_LDM_VS: "LDM.VS",
+ arm_LDM_VC: "LDM.VC",
+ arm_LDM_HI: "LDM.HI",
+ arm_LDM_LS: "LDM.LS",
+ arm_LDM_GE: "LDM.GE",
+ arm_LDM_LT: "LDM.LT",
+ arm_LDM_GT: "LDM.GT",
+ arm_LDM_LE: "LDM.LE",
+ arm_LDM: "LDM",
+ arm_LDM_ZZ: "LDM.ZZ",
+ arm_LDMDA_EQ: "LDMDA.EQ",
+ arm_LDMDA_NE: "LDMDA.NE",
+ arm_LDMDA_CS: "LDMDA.CS",
+ arm_LDMDA_CC: "LDMDA.CC",
+ arm_LDMDA_MI: "LDMDA.MI",
+ arm_LDMDA_PL: "LDMDA.PL",
+ arm_LDMDA_VS: "LDMDA.VS",
+ arm_LDMDA_VC: "LDMDA.VC",
+ arm_LDMDA_HI: "LDMDA.HI",
+ arm_LDMDA_LS: "LDMDA.LS",
+ arm_LDMDA_GE: "LDMDA.GE",
+ arm_LDMDA_LT: "LDMDA.LT",
+ arm_LDMDA_GT: "LDMDA.GT",
+ arm_LDMDA_LE: "LDMDA.LE",
+ arm_LDMDA: "LDMDA",
+ arm_LDMDA_ZZ: "LDMDA.ZZ",
+ arm_LDMDB_EQ: "LDMDB.EQ",
+ arm_LDMDB_NE: "LDMDB.NE",
+ arm_LDMDB_CS: "LDMDB.CS",
+ arm_LDMDB_CC: "LDMDB.CC",
+ arm_LDMDB_MI: "LDMDB.MI",
+ arm_LDMDB_PL: "LDMDB.PL",
+ arm_LDMDB_VS: "LDMDB.VS",
+ arm_LDMDB_VC: "LDMDB.VC",
+ arm_LDMDB_HI: "LDMDB.HI",
+ arm_LDMDB_LS: "LDMDB.LS",
+ arm_LDMDB_GE: "LDMDB.GE",
+ arm_LDMDB_LT: "LDMDB.LT",
+ arm_LDMDB_GT: "LDMDB.GT",
+ arm_LDMDB_LE: "LDMDB.LE",
+ arm_LDMDB: "LDMDB",
+ arm_LDMDB_ZZ: "LDMDB.ZZ",
+ arm_LDMIB_EQ: "LDMIB.EQ",
+ arm_LDMIB_NE: "LDMIB.NE",
+ arm_LDMIB_CS: "LDMIB.CS",
+ arm_LDMIB_CC: "LDMIB.CC",
+ arm_LDMIB_MI: "LDMIB.MI",
+ arm_LDMIB_PL: "LDMIB.PL",
+ arm_LDMIB_VS: "LDMIB.VS",
+ arm_LDMIB_VC: "LDMIB.VC",
+ arm_LDMIB_HI: "LDMIB.HI",
+ arm_LDMIB_LS: "LDMIB.LS",
+ arm_LDMIB_GE: "LDMIB.GE",
+ arm_LDMIB_LT: "LDMIB.LT",
+ arm_LDMIB_GT: "LDMIB.GT",
+ arm_LDMIB_LE: "LDMIB.LE",
+ arm_LDMIB: "LDMIB",
+ arm_LDMIB_ZZ: "LDMIB.ZZ",
+ arm_LDR_EQ: "LDR.EQ",
+ arm_LDR_NE: "LDR.NE",
+ arm_LDR_CS: "LDR.CS",
+ arm_LDR_CC: "LDR.CC",
+ arm_LDR_MI: "LDR.MI",
+ arm_LDR_PL: "LDR.PL",
+ arm_LDR_VS: "LDR.VS",
+ arm_LDR_VC: "LDR.VC",
+ arm_LDR_HI: "LDR.HI",
+ arm_LDR_LS: "LDR.LS",
+ arm_LDR_GE: "LDR.GE",
+ arm_LDR_LT: "LDR.LT",
+ arm_LDR_GT: "LDR.GT",
+ arm_LDR_LE: "LDR.LE",
+ arm_LDR: "LDR",
+ arm_LDR_ZZ: "LDR.ZZ",
+ arm_LDRB_EQ: "LDRB.EQ",
+ arm_LDRB_NE: "LDRB.NE",
+ arm_LDRB_CS: "LDRB.CS",
+ arm_LDRB_CC: "LDRB.CC",
+ arm_LDRB_MI: "LDRB.MI",
+ arm_LDRB_PL: "LDRB.PL",
+ arm_LDRB_VS: "LDRB.VS",
+ arm_LDRB_VC: "LDRB.VC",
+ arm_LDRB_HI: "LDRB.HI",
+ arm_LDRB_LS: "LDRB.LS",
+ arm_LDRB_GE: "LDRB.GE",
+ arm_LDRB_LT: "LDRB.LT",
+ arm_LDRB_GT: "LDRB.GT",
+ arm_LDRB_LE: "LDRB.LE",
+ arm_LDRB: "LDRB",
+ arm_LDRB_ZZ: "LDRB.ZZ",
+ arm_LDRBT_EQ: "LDRBT.EQ",
+ arm_LDRBT_NE: "LDRBT.NE",
+ arm_LDRBT_CS: "LDRBT.CS",
+ arm_LDRBT_CC: "LDRBT.CC",
+ arm_LDRBT_MI: "LDRBT.MI",
+ arm_LDRBT_PL: "LDRBT.PL",
+ arm_LDRBT_VS: "LDRBT.VS",
+ arm_LDRBT_VC: "LDRBT.VC",
+ arm_LDRBT_HI: "LDRBT.HI",
+ arm_LDRBT_LS: "LDRBT.LS",
+ arm_LDRBT_GE: "LDRBT.GE",
+ arm_LDRBT_LT: "LDRBT.LT",
+ arm_LDRBT_GT: "LDRBT.GT",
+ arm_LDRBT_LE: "LDRBT.LE",
+ arm_LDRBT: "LDRBT",
+ arm_LDRBT_ZZ: "LDRBT.ZZ",
+ arm_LDRD_EQ: "LDRD.EQ",
+ arm_LDRD_NE: "LDRD.NE",
+ arm_LDRD_CS: "LDRD.CS",
+ arm_LDRD_CC: "LDRD.CC",
+ arm_LDRD_MI: "LDRD.MI",
+ arm_LDRD_PL: "LDRD.PL",
+ arm_LDRD_VS: "LDRD.VS",
+ arm_LDRD_VC: "LDRD.VC",
+ arm_LDRD_HI: "LDRD.HI",
+ arm_LDRD_LS: "LDRD.LS",
+ arm_LDRD_GE: "LDRD.GE",
+ arm_LDRD_LT: "LDRD.LT",
+ arm_LDRD_GT: "LDRD.GT",
+ arm_LDRD_LE: "LDRD.LE",
+ arm_LDRD: "LDRD",
+ arm_LDRD_ZZ: "LDRD.ZZ",
+ arm_LDREX_EQ: "LDREX.EQ",
+ arm_LDREX_NE: "LDREX.NE",
+ arm_LDREX_CS: "LDREX.CS",
+ arm_LDREX_CC: "LDREX.CC",
+ arm_LDREX_MI: "LDREX.MI",
+ arm_LDREX_PL: "LDREX.PL",
+ arm_LDREX_VS: "LDREX.VS",
+ arm_LDREX_VC: "LDREX.VC",
+ arm_LDREX_HI: "LDREX.HI",
+ arm_LDREX_LS: "LDREX.LS",
+ arm_LDREX_GE: "LDREX.GE",
+ arm_LDREX_LT: "LDREX.LT",
+ arm_LDREX_GT: "LDREX.GT",
+ arm_LDREX_LE: "LDREX.LE",
+ arm_LDREX: "LDREX",
+ arm_LDREX_ZZ: "LDREX.ZZ",
+ arm_LDREXB_EQ: "LDREXB.EQ",
+ arm_LDREXB_NE: "LDREXB.NE",
+ arm_LDREXB_CS: "LDREXB.CS",
+ arm_LDREXB_CC: "LDREXB.CC",
+ arm_LDREXB_MI: "LDREXB.MI",
+ arm_LDREXB_PL: "LDREXB.PL",
+ arm_LDREXB_VS: "LDREXB.VS",
+ arm_LDREXB_VC: "LDREXB.VC",
+ arm_LDREXB_HI: "LDREXB.HI",
+ arm_LDREXB_LS: "LDREXB.LS",
+ arm_LDREXB_GE: "LDREXB.GE",
+ arm_LDREXB_LT: "LDREXB.LT",
+ arm_LDREXB_GT: "LDREXB.GT",
+ arm_LDREXB_LE: "LDREXB.LE",
+ arm_LDREXB: "LDREXB",
+ arm_LDREXB_ZZ: "LDREXB.ZZ",
+ arm_LDREXD_EQ: "LDREXD.EQ",
+ arm_LDREXD_NE: "LDREXD.NE",
+ arm_LDREXD_CS: "LDREXD.CS",
+ arm_LDREXD_CC: "LDREXD.CC",
+ arm_LDREXD_MI: "LDREXD.MI",
+ arm_LDREXD_PL: "LDREXD.PL",
+ arm_LDREXD_VS: "LDREXD.VS",
+ arm_LDREXD_VC: "LDREXD.VC",
+ arm_LDREXD_HI: "LDREXD.HI",
+ arm_LDREXD_LS: "LDREXD.LS",
+ arm_LDREXD_GE: "LDREXD.GE",
+ arm_LDREXD_LT: "LDREXD.LT",
+ arm_LDREXD_GT: "LDREXD.GT",
+ arm_LDREXD_LE: "LDREXD.LE",
+ arm_LDREXD: "LDREXD",
+ arm_LDREXD_ZZ: "LDREXD.ZZ",
+ arm_LDREXH_EQ: "LDREXH.EQ",
+ arm_LDREXH_NE: "LDREXH.NE",
+ arm_LDREXH_CS: "LDREXH.CS",
+ arm_LDREXH_CC: "LDREXH.CC",
+ arm_LDREXH_MI: "LDREXH.MI",
+ arm_LDREXH_PL: "LDREXH.PL",
+ arm_LDREXH_VS: "LDREXH.VS",
+ arm_LDREXH_VC: "LDREXH.VC",
+ arm_LDREXH_HI: "LDREXH.HI",
+ arm_LDREXH_LS: "LDREXH.LS",
+ arm_LDREXH_GE: "LDREXH.GE",
+ arm_LDREXH_LT: "LDREXH.LT",
+ arm_LDREXH_GT: "LDREXH.GT",
+ arm_LDREXH_LE: "LDREXH.LE",
+ arm_LDREXH: "LDREXH",
+ arm_LDREXH_ZZ: "LDREXH.ZZ",
+ arm_LDRH_EQ: "LDRH.EQ",
+ arm_LDRH_NE: "LDRH.NE",
+ arm_LDRH_CS: "LDRH.CS",
+ arm_LDRH_CC: "LDRH.CC",
+ arm_LDRH_MI: "LDRH.MI",
+ arm_LDRH_PL: "LDRH.PL",
+ arm_LDRH_VS: "LDRH.VS",
+ arm_LDRH_VC: "LDRH.VC",
+ arm_LDRH_HI: "LDRH.HI",
+ arm_LDRH_LS: "LDRH.LS",
+ arm_LDRH_GE: "LDRH.GE",
+ arm_LDRH_LT: "LDRH.LT",
+ arm_LDRH_GT: "LDRH.GT",
+ arm_LDRH_LE: "LDRH.LE",
+ arm_LDRH: "LDRH",
+ arm_LDRH_ZZ: "LDRH.ZZ",
+ arm_LDRHT_EQ: "LDRHT.EQ",
+ arm_LDRHT_NE: "LDRHT.NE",
+ arm_LDRHT_CS: "LDRHT.CS",
+ arm_LDRHT_CC: "LDRHT.CC",
+ arm_LDRHT_MI: "LDRHT.MI",
+ arm_LDRHT_PL: "LDRHT.PL",
+ arm_LDRHT_VS: "LDRHT.VS",
+ arm_LDRHT_VC: "LDRHT.VC",
+ arm_LDRHT_HI: "LDRHT.HI",
+ arm_LDRHT_LS: "LDRHT.LS",
+ arm_LDRHT_GE: "LDRHT.GE",
+ arm_LDRHT_LT: "LDRHT.LT",
+ arm_LDRHT_GT: "LDRHT.GT",
+ arm_LDRHT_LE: "LDRHT.LE",
+ arm_LDRHT: "LDRHT",
+ arm_LDRHT_ZZ: "LDRHT.ZZ",
+ arm_LDRSB_EQ: "LDRSB.EQ",
+ arm_LDRSB_NE: "LDRSB.NE",
+ arm_LDRSB_CS: "LDRSB.CS",
+ arm_LDRSB_CC: "LDRSB.CC",
+ arm_LDRSB_MI: "LDRSB.MI",
+ arm_LDRSB_PL: "LDRSB.PL",
+ arm_LDRSB_VS: "LDRSB.VS",
+ arm_LDRSB_VC: "LDRSB.VC",
+ arm_LDRSB_HI: "LDRSB.HI",
+ arm_LDRSB_LS: "LDRSB.LS",
+ arm_LDRSB_GE: "LDRSB.GE",
+ arm_LDRSB_LT: "LDRSB.LT",
+ arm_LDRSB_GT: "LDRSB.GT",
+ arm_LDRSB_LE: "LDRSB.LE",
+ arm_LDRSB: "LDRSB",
+ arm_LDRSB_ZZ: "LDRSB.ZZ",
+ arm_LDRSBT_EQ: "LDRSBT.EQ",
+ arm_LDRSBT_NE: "LDRSBT.NE",
+ arm_LDRSBT_CS: "LDRSBT.CS",
+ arm_LDRSBT_CC: "LDRSBT.CC",
+ arm_LDRSBT_MI: "LDRSBT.MI",
+ arm_LDRSBT_PL: "LDRSBT.PL",
+ arm_LDRSBT_VS: "LDRSBT.VS",
+ arm_LDRSBT_VC: "LDRSBT.VC",
+ arm_LDRSBT_HI: "LDRSBT.HI",
+ arm_LDRSBT_LS: "LDRSBT.LS",
+ arm_LDRSBT_GE: "LDRSBT.GE",
+ arm_LDRSBT_LT: "LDRSBT.LT",
+ arm_LDRSBT_GT: "LDRSBT.GT",
+ arm_LDRSBT_LE: "LDRSBT.LE",
+ arm_LDRSBT: "LDRSBT",
+ arm_LDRSBT_ZZ: "LDRSBT.ZZ",
+ arm_LDRSH_EQ: "LDRSH.EQ",
+ arm_LDRSH_NE: "LDRSH.NE",
+ arm_LDRSH_CS: "LDRSH.CS",
+ arm_LDRSH_CC: "LDRSH.CC",
+ arm_LDRSH_MI: "LDRSH.MI",
+ arm_LDRSH_PL: "LDRSH.PL",
+ arm_LDRSH_VS: "LDRSH.VS",
+ arm_LDRSH_VC: "LDRSH.VC",
+ arm_LDRSH_HI: "LDRSH.HI",
+ arm_LDRSH_LS: "LDRSH.LS",
+ arm_LDRSH_GE: "LDRSH.GE",
+ arm_LDRSH_LT: "LDRSH.LT",
+ arm_LDRSH_GT: "LDRSH.GT",
+ arm_LDRSH_LE: "LDRSH.LE",
+ arm_LDRSH: "LDRSH",
+ arm_LDRSH_ZZ: "LDRSH.ZZ",
+ arm_LDRSHT_EQ: "LDRSHT.EQ",
+ arm_LDRSHT_NE: "LDRSHT.NE",
+ arm_LDRSHT_CS: "LDRSHT.CS",
+ arm_LDRSHT_CC: "LDRSHT.CC",
+ arm_LDRSHT_MI: "LDRSHT.MI",
+ arm_LDRSHT_PL: "LDRSHT.PL",
+ arm_LDRSHT_VS: "LDRSHT.VS",
+ arm_LDRSHT_VC: "LDRSHT.VC",
+ arm_LDRSHT_HI: "LDRSHT.HI",
+ arm_LDRSHT_LS: "LDRSHT.LS",
+ arm_LDRSHT_GE: "LDRSHT.GE",
+ arm_LDRSHT_LT: "LDRSHT.LT",
+ arm_LDRSHT_GT: "LDRSHT.GT",
+ arm_LDRSHT_LE: "LDRSHT.LE",
+ arm_LDRSHT: "LDRSHT",
+ arm_LDRSHT_ZZ: "LDRSHT.ZZ",
+ arm_LDRT_EQ: "LDRT.EQ",
+ arm_LDRT_NE: "LDRT.NE",
+ arm_LDRT_CS: "LDRT.CS",
+ arm_LDRT_CC: "LDRT.CC",
+ arm_LDRT_MI: "LDRT.MI",
+ arm_LDRT_PL: "LDRT.PL",
+ arm_LDRT_VS: "LDRT.VS",
+ arm_LDRT_VC: "LDRT.VC",
+ arm_LDRT_HI: "LDRT.HI",
+ arm_LDRT_LS: "LDRT.LS",
+ arm_LDRT_GE: "LDRT.GE",
+ arm_LDRT_LT: "LDRT.LT",
+ arm_LDRT_GT: "LDRT.GT",
+ arm_LDRT_LE: "LDRT.LE",
+ arm_LDRT: "LDRT",
+ arm_LDRT_ZZ: "LDRT.ZZ",
+ arm_LSL_EQ: "LSL.EQ",
+ arm_LSL_NE: "LSL.NE",
+ arm_LSL_CS: "LSL.CS",
+ arm_LSL_CC: "LSL.CC",
+ arm_LSL_MI: "LSL.MI",
+ arm_LSL_PL: "LSL.PL",
+ arm_LSL_VS: "LSL.VS",
+ arm_LSL_VC: "LSL.VC",
+ arm_LSL_HI: "LSL.HI",
+ arm_LSL_LS: "LSL.LS",
+ arm_LSL_GE: "LSL.GE",
+ arm_LSL_LT: "LSL.LT",
+ arm_LSL_GT: "LSL.GT",
+ arm_LSL_LE: "LSL.LE",
+ arm_LSL: "LSL",
+ arm_LSL_ZZ: "LSL.ZZ",
+ arm_LSL_S_EQ: "LSL.S.EQ",
+ arm_LSL_S_NE: "LSL.S.NE",
+ arm_LSL_S_CS: "LSL.S.CS",
+ arm_LSL_S_CC: "LSL.S.CC",
+ arm_LSL_S_MI: "LSL.S.MI",
+ arm_LSL_S_PL: "LSL.S.PL",
+ arm_LSL_S_VS: "LSL.S.VS",
+ arm_LSL_S_VC: "LSL.S.VC",
+ arm_LSL_S_HI: "LSL.S.HI",
+ arm_LSL_S_LS: "LSL.S.LS",
+ arm_LSL_S_GE: "LSL.S.GE",
+ arm_LSL_S_LT: "LSL.S.LT",
+ arm_LSL_S_GT: "LSL.S.GT",
+ arm_LSL_S_LE: "LSL.S.LE",
+ arm_LSL_S: "LSL.S",
+ arm_LSL_S_ZZ: "LSL.S.ZZ",
+ arm_LSR_EQ: "LSR.EQ",
+ arm_LSR_NE: "LSR.NE",
+ arm_LSR_CS: "LSR.CS",
+ arm_LSR_CC: "LSR.CC",
+ arm_LSR_MI: "LSR.MI",
+ arm_LSR_PL: "LSR.PL",
+ arm_LSR_VS: "LSR.VS",
+ arm_LSR_VC: "LSR.VC",
+ arm_LSR_HI: "LSR.HI",
+ arm_LSR_LS: "LSR.LS",
+ arm_LSR_GE: "LSR.GE",
+ arm_LSR_LT: "LSR.LT",
+ arm_LSR_GT: "LSR.GT",
+ arm_LSR_LE: "LSR.LE",
+ arm_LSR: "LSR",
+ arm_LSR_ZZ: "LSR.ZZ",
+ arm_LSR_S_EQ: "LSR.S.EQ",
+ arm_LSR_S_NE: "LSR.S.NE",
+ arm_LSR_S_CS: "LSR.S.CS",
+ arm_LSR_S_CC: "LSR.S.CC",
+ arm_LSR_S_MI: "LSR.S.MI",
+ arm_LSR_S_PL: "LSR.S.PL",
+ arm_LSR_S_VS: "LSR.S.VS",
+ arm_LSR_S_VC: "LSR.S.VC",
+ arm_LSR_S_HI: "LSR.S.HI",
+ arm_LSR_S_LS: "LSR.S.LS",
+ arm_LSR_S_GE: "LSR.S.GE",
+ arm_LSR_S_LT: "LSR.S.LT",
+ arm_LSR_S_GT: "LSR.S.GT",
+ arm_LSR_S_LE: "LSR.S.LE",
+ arm_LSR_S: "LSR.S",
+ arm_LSR_S_ZZ: "LSR.S.ZZ",
+ arm_MLA_EQ: "MLA.EQ",
+ arm_MLA_NE: "MLA.NE",
+ arm_MLA_CS: "MLA.CS",
+ arm_MLA_CC: "MLA.CC",
+ arm_MLA_MI: "MLA.MI",
+ arm_MLA_PL: "MLA.PL",
+ arm_MLA_VS: "MLA.VS",
+ arm_MLA_VC: "MLA.VC",
+ arm_MLA_HI: "MLA.HI",
+ arm_MLA_LS: "MLA.LS",
+ arm_MLA_GE: "MLA.GE",
+ arm_MLA_LT: "MLA.LT",
+ arm_MLA_GT: "MLA.GT",
+ arm_MLA_LE: "MLA.LE",
+ arm_MLA: "MLA",
+ arm_MLA_ZZ: "MLA.ZZ",
+ arm_MLA_S_EQ: "MLA.S.EQ",
+ arm_MLA_S_NE: "MLA.S.NE",
+ arm_MLA_S_CS: "MLA.S.CS",
+ arm_MLA_S_CC: "MLA.S.CC",
+ arm_MLA_S_MI: "MLA.S.MI",
+ arm_MLA_S_PL: "MLA.S.PL",
+ arm_MLA_S_VS: "MLA.S.VS",
+ arm_MLA_S_VC: "MLA.S.VC",
+ arm_MLA_S_HI: "MLA.S.HI",
+ arm_MLA_S_LS: "MLA.S.LS",
+ arm_MLA_S_GE: "MLA.S.GE",
+ arm_MLA_S_LT: "MLA.S.LT",
+ arm_MLA_S_GT: "MLA.S.GT",
+ arm_MLA_S_LE: "MLA.S.LE",
+ arm_MLA_S: "MLA.S",
+ arm_MLA_S_ZZ: "MLA.S.ZZ",
+ arm_MLS_EQ: "MLS.EQ",
+ arm_MLS_NE: "MLS.NE",
+ arm_MLS_CS: "MLS.CS",
+ arm_MLS_CC: "MLS.CC",
+ arm_MLS_MI: "MLS.MI",
+ arm_MLS_PL: "MLS.PL",
+ arm_MLS_VS: "MLS.VS",
+ arm_MLS_VC: "MLS.VC",
+ arm_MLS_HI: "MLS.HI",
+ arm_MLS_LS: "MLS.LS",
+ arm_MLS_GE: "MLS.GE",
+ arm_MLS_LT: "MLS.LT",
+ arm_MLS_GT: "MLS.GT",
+ arm_MLS_LE: "MLS.LE",
+ arm_MLS: "MLS",
+ arm_MLS_ZZ: "MLS.ZZ",
+ arm_MOV_EQ: "MOV.EQ",
+ arm_MOV_NE: "MOV.NE",
+ arm_MOV_CS: "MOV.CS",
+ arm_MOV_CC: "MOV.CC",
+ arm_MOV_MI: "MOV.MI",
+ arm_MOV_PL: "MOV.PL",
+ arm_MOV_VS: "MOV.VS",
+ arm_MOV_VC: "MOV.VC",
+ arm_MOV_HI: "MOV.HI",
+ arm_MOV_LS: "MOV.LS",
+ arm_MOV_GE: "MOV.GE",
+ arm_MOV_LT: "MOV.LT",
+ arm_MOV_GT: "MOV.GT",
+ arm_MOV_LE: "MOV.LE",
+ arm_MOV: "MOV",
+ arm_MOV_ZZ: "MOV.ZZ",
+ arm_MOV_S_EQ: "MOV.S.EQ",
+ arm_MOV_S_NE: "MOV.S.NE",
+ arm_MOV_S_CS: "MOV.S.CS",
+ arm_MOV_S_CC: "MOV.S.CC",
+ arm_MOV_S_MI: "MOV.S.MI",
+ arm_MOV_S_PL: "MOV.S.PL",
+ arm_MOV_S_VS: "MOV.S.VS",
+ arm_MOV_S_VC: "MOV.S.VC",
+ arm_MOV_S_HI: "MOV.S.HI",
+ arm_MOV_S_LS: "MOV.S.LS",
+ arm_MOV_S_GE: "MOV.S.GE",
+ arm_MOV_S_LT: "MOV.S.LT",
+ arm_MOV_S_GT: "MOV.S.GT",
+ arm_MOV_S_LE: "MOV.S.LE",
+ arm_MOV_S: "MOV.S",
+ arm_MOV_S_ZZ: "MOV.S.ZZ",
+ arm_MOVT_EQ: "MOVT.EQ",
+ arm_MOVT_NE: "MOVT.NE",
+ arm_MOVT_CS: "MOVT.CS",
+ arm_MOVT_CC: "MOVT.CC",
+ arm_MOVT_MI: "MOVT.MI",
+ arm_MOVT_PL: "MOVT.PL",
+ arm_MOVT_VS: "MOVT.VS",
+ arm_MOVT_VC: "MOVT.VC",
+ arm_MOVT_HI: "MOVT.HI",
+ arm_MOVT_LS: "MOVT.LS",
+ arm_MOVT_GE: "MOVT.GE",
+ arm_MOVT_LT: "MOVT.LT",
+ arm_MOVT_GT: "MOVT.GT",
+ arm_MOVT_LE: "MOVT.LE",
+ arm_MOVT: "MOVT",
+ arm_MOVT_ZZ: "MOVT.ZZ",
+ arm_MOVW_EQ: "MOVW.EQ",
+ arm_MOVW_NE: "MOVW.NE",
+ arm_MOVW_CS: "MOVW.CS",
+ arm_MOVW_CC: "MOVW.CC",
+ arm_MOVW_MI: "MOVW.MI",
+ arm_MOVW_PL: "MOVW.PL",
+ arm_MOVW_VS: "MOVW.VS",
+ arm_MOVW_VC: "MOVW.VC",
+ arm_MOVW_HI: "MOVW.HI",
+ arm_MOVW_LS: "MOVW.LS",
+ arm_MOVW_GE: "MOVW.GE",
+ arm_MOVW_LT: "MOVW.LT",
+ arm_MOVW_GT: "MOVW.GT",
+ arm_MOVW_LE: "MOVW.LE",
+ arm_MOVW: "MOVW",
+ arm_MOVW_ZZ: "MOVW.ZZ",
+ arm_MRS_EQ: "MRS.EQ",
+ arm_MRS_NE: "MRS.NE",
+ arm_MRS_CS: "MRS.CS",
+ arm_MRS_CC: "MRS.CC",
+ arm_MRS_MI: "MRS.MI",
+ arm_MRS_PL: "MRS.PL",
+ arm_MRS_VS: "MRS.VS",
+ arm_MRS_VC: "MRS.VC",
+ arm_MRS_HI: "MRS.HI",
+ arm_MRS_LS: "MRS.LS",
+ arm_MRS_GE: "MRS.GE",
+ arm_MRS_LT: "MRS.LT",
+ arm_MRS_GT: "MRS.GT",
+ arm_MRS_LE: "MRS.LE",
+ arm_MRS: "MRS",
+ arm_MRS_ZZ: "MRS.ZZ",
+ arm_MUL_EQ: "MUL.EQ",
+ arm_MUL_NE: "MUL.NE",
+ arm_MUL_CS: "MUL.CS",
+ arm_MUL_CC: "MUL.CC",
+ arm_MUL_MI: "MUL.MI",
+ arm_MUL_PL: "MUL.PL",
+ arm_MUL_VS: "MUL.VS",
+ arm_MUL_VC: "MUL.VC",
+ arm_MUL_HI: "MUL.HI",
+ arm_MUL_LS: "MUL.LS",
+ arm_MUL_GE: "MUL.GE",
+ arm_MUL_LT: "MUL.LT",
+ arm_MUL_GT: "MUL.GT",
+ arm_MUL_LE: "MUL.LE",
+ arm_MUL: "MUL",
+ arm_MUL_ZZ: "MUL.ZZ",
+ arm_MUL_S_EQ: "MUL.S.EQ",
+ arm_MUL_S_NE: "MUL.S.NE",
+ arm_MUL_S_CS: "MUL.S.CS",
+ arm_MUL_S_CC: "MUL.S.CC",
+ arm_MUL_S_MI: "MUL.S.MI",
+ arm_MUL_S_PL: "MUL.S.PL",
+ arm_MUL_S_VS: "MUL.S.VS",
+ arm_MUL_S_VC: "MUL.S.VC",
+ arm_MUL_S_HI: "MUL.S.HI",
+ arm_MUL_S_LS: "MUL.S.LS",
+ arm_MUL_S_GE: "MUL.S.GE",
+ arm_MUL_S_LT: "MUL.S.LT",
+ arm_MUL_S_GT: "MUL.S.GT",
+ arm_MUL_S_LE: "MUL.S.LE",
+ arm_MUL_S: "MUL.S",
+ arm_MUL_S_ZZ: "MUL.S.ZZ",
+ arm_MVN_EQ: "MVN.EQ",
+ arm_MVN_NE: "MVN.NE",
+ arm_MVN_CS: "MVN.CS",
+ arm_MVN_CC: "MVN.CC",
+ arm_MVN_MI: "MVN.MI",
+ arm_MVN_PL: "MVN.PL",
+ arm_MVN_VS: "MVN.VS",
+ arm_MVN_VC: "MVN.VC",
+ arm_MVN_HI: "MVN.HI",
+ arm_MVN_LS: "MVN.LS",
+ arm_MVN_GE: "MVN.GE",
+ arm_MVN_LT: "MVN.LT",
+ arm_MVN_GT: "MVN.GT",
+ arm_MVN_LE: "MVN.LE",
+ arm_MVN: "MVN",
+ arm_MVN_ZZ: "MVN.ZZ",
+ arm_MVN_S_EQ: "MVN.S.EQ",
+ arm_MVN_S_NE: "MVN.S.NE",
+ arm_MVN_S_CS: "MVN.S.CS",
+ arm_MVN_S_CC: "MVN.S.CC",
+ arm_MVN_S_MI: "MVN.S.MI",
+ arm_MVN_S_PL: "MVN.S.PL",
+ arm_MVN_S_VS: "MVN.S.VS",
+ arm_MVN_S_VC: "MVN.S.VC",
+ arm_MVN_S_HI: "MVN.S.HI",
+ arm_MVN_S_LS: "MVN.S.LS",
+ arm_MVN_S_GE: "MVN.S.GE",
+ arm_MVN_S_LT: "MVN.S.LT",
+ arm_MVN_S_GT: "MVN.S.GT",
+ arm_MVN_S_LE: "MVN.S.LE",
+ arm_MVN_S: "MVN.S",
+ arm_MVN_S_ZZ: "MVN.S.ZZ",
+ arm_NOP_EQ: "NOP.EQ",
+ arm_NOP_NE: "NOP.NE",
+ arm_NOP_CS: "NOP.CS",
+ arm_NOP_CC: "NOP.CC",
+ arm_NOP_MI: "NOP.MI",
+ arm_NOP_PL: "NOP.PL",
+ arm_NOP_VS: "NOP.VS",
+ arm_NOP_VC: "NOP.VC",
+ arm_NOP_HI: "NOP.HI",
+ arm_NOP_LS: "NOP.LS",
+ arm_NOP_GE: "NOP.GE",
+ arm_NOP_LT: "NOP.LT",
+ arm_NOP_GT: "NOP.GT",
+ arm_NOP_LE: "NOP.LE",
+ arm_NOP: "NOP",
+ arm_NOP_ZZ: "NOP.ZZ",
+ arm_ORR_EQ: "ORR.EQ",
+ arm_ORR_NE: "ORR.NE",
+ arm_ORR_CS: "ORR.CS",
+ arm_ORR_CC: "ORR.CC",
+ arm_ORR_MI: "ORR.MI",
+ arm_ORR_PL: "ORR.PL",
+ arm_ORR_VS: "ORR.VS",
+ arm_ORR_VC: "ORR.VC",
+ arm_ORR_HI: "ORR.HI",
+ arm_ORR_LS: "ORR.LS",
+ arm_ORR_GE: "ORR.GE",
+ arm_ORR_LT: "ORR.LT",
+ arm_ORR_GT: "ORR.GT",
+ arm_ORR_LE: "ORR.LE",
+ arm_ORR: "ORR",
+ arm_ORR_ZZ: "ORR.ZZ",
+ arm_ORR_S_EQ: "ORR.S.EQ",
+ arm_ORR_S_NE: "ORR.S.NE",
+ arm_ORR_S_CS: "ORR.S.CS",
+ arm_ORR_S_CC: "ORR.S.CC",
+ arm_ORR_S_MI: "ORR.S.MI",
+ arm_ORR_S_PL: "ORR.S.PL",
+ arm_ORR_S_VS: "ORR.S.VS",
+ arm_ORR_S_VC: "ORR.S.VC",
+ arm_ORR_S_HI: "ORR.S.HI",
+ arm_ORR_S_LS: "ORR.S.LS",
+ arm_ORR_S_GE: "ORR.S.GE",
+ arm_ORR_S_LT: "ORR.S.LT",
+ arm_ORR_S_GT: "ORR.S.GT",
+ arm_ORR_S_LE: "ORR.S.LE",
+ arm_ORR_S: "ORR.S",
+ arm_ORR_S_ZZ: "ORR.S.ZZ",
+ arm_PKHBT_EQ: "PKHBT.EQ",
+ arm_PKHBT_NE: "PKHBT.NE",
+ arm_PKHBT_CS: "PKHBT.CS",
+ arm_PKHBT_CC: "PKHBT.CC",
+ arm_PKHBT_MI: "PKHBT.MI",
+ arm_PKHBT_PL: "PKHBT.PL",
+ arm_PKHBT_VS: "PKHBT.VS",
+ arm_PKHBT_VC: "PKHBT.VC",
+ arm_PKHBT_HI: "PKHBT.HI",
+ arm_PKHBT_LS: "PKHBT.LS",
+ arm_PKHBT_GE: "PKHBT.GE",
+ arm_PKHBT_LT: "PKHBT.LT",
+ arm_PKHBT_GT: "PKHBT.GT",
+ arm_PKHBT_LE: "PKHBT.LE",
+ arm_PKHBT: "PKHBT",
+ arm_PKHBT_ZZ: "PKHBT.ZZ",
+ arm_PKHTB_EQ: "PKHTB.EQ",
+ arm_PKHTB_NE: "PKHTB.NE",
+ arm_PKHTB_CS: "PKHTB.CS",
+ arm_PKHTB_CC: "PKHTB.CC",
+ arm_PKHTB_MI: "PKHTB.MI",
+ arm_PKHTB_PL: "PKHTB.PL",
+ arm_PKHTB_VS: "PKHTB.VS",
+ arm_PKHTB_VC: "PKHTB.VC",
+ arm_PKHTB_HI: "PKHTB.HI",
+ arm_PKHTB_LS: "PKHTB.LS",
+ arm_PKHTB_GE: "PKHTB.GE",
+ arm_PKHTB_LT: "PKHTB.LT",
+ arm_PKHTB_GT: "PKHTB.GT",
+ arm_PKHTB_LE: "PKHTB.LE",
+ arm_PKHTB: "PKHTB",
+ arm_PKHTB_ZZ: "PKHTB.ZZ",
+ arm_PLD_W: "PLD.W",
+ arm_PLD: "PLD",
+ arm_PLI: "PLI",
+ arm_POP_EQ: "POP.EQ",
+ arm_POP_NE: "POP.NE",
+ arm_POP_CS: "POP.CS",
+ arm_POP_CC: "POP.CC",
+ arm_POP_MI: "POP.MI",
+ arm_POP_PL: "POP.PL",
+ arm_POP_VS: "POP.VS",
+ arm_POP_VC: "POP.VC",
+ arm_POP_HI: "POP.HI",
+ arm_POP_LS: "POP.LS",
+ arm_POP_GE: "POP.GE",
+ arm_POP_LT: "POP.LT",
+ arm_POP_GT: "POP.GT",
+ arm_POP_LE: "POP.LE",
+ arm_POP: "POP",
+ arm_POP_ZZ: "POP.ZZ",
+ arm_PUSH_EQ: "PUSH.EQ",
+ arm_PUSH_NE: "PUSH.NE",
+ arm_PUSH_CS: "PUSH.CS",
+ arm_PUSH_CC: "PUSH.CC",
+ arm_PUSH_MI: "PUSH.MI",
+ arm_PUSH_PL: "PUSH.PL",
+ arm_PUSH_VS: "PUSH.VS",
+ arm_PUSH_VC: "PUSH.VC",
+ arm_PUSH_HI: "PUSH.HI",
+ arm_PUSH_LS: "PUSH.LS",
+ arm_PUSH_GE: "PUSH.GE",
+ arm_PUSH_LT: "PUSH.LT",
+ arm_PUSH_GT: "PUSH.GT",
+ arm_PUSH_LE: "PUSH.LE",
+ arm_PUSH: "PUSH",
+ arm_PUSH_ZZ: "PUSH.ZZ",
+ arm_QADD_EQ: "QADD.EQ",
+ arm_QADD_NE: "QADD.NE",
+ arm_QADD_CS: "QADD.CS",
+ arm_QADD_CC: "QADD.CC",
+ arm_QADD_MI: "QADD.MI",
+ arm_QADD_PL: "QADD.PL",
+ arm_QADD_VS: "QADD.VS",
+ arm_QADD_VC: "QADD.VC",
+ arm_QADD_HI: "QADD.HI",
+ arm_QADD_LS: "QADD.LS",
+ arm_QADD_GE: "QADD.GE",
+ arm_QADD_LT: "QADD.LT",
+ arm_QADD_GT: "QADD.GT",
+ arm_QADD_LE: "QADD.LE",
+ arm_QADD: "QADD",
+ arm_QADD_ZZ: "QADD.ZZ",
+ arm_QADD16_EQ: "QADD16.EQ",
+ arm_QADD16_NE: "QADD16.NE",
+ arm_QADD16_CS: "QADD16.CS",
+ arm_QADD16_CC: "QADD16.CC",
+ arm_QADD16_MI: "QADD16.MI",
+ arm_QADD16_PL: "QADD16.PL",
+ arm_QADD16_VS: "QADD16.VS",
+ arm_QADD16_VC: "QADD16.VC",
+ arm_QADD16_HI: "QADD16.HI",
+ arm_QADD16_LS: "QADD16.LS",
+ arm_QADD16_GE: "QADD16.GE",
+ arm_QADD16_LT: "QADD16.LT",
+ arm_QADD16_GT: "QADD16.GT",
+ arm_QADD16_LE: "QADD16.LE",
+ arm_QADD16: "QADD16",
+ arm_QADD16_ZZ: "QADD16.ZZ",
+ arm_QADD8_EQ: "QADD8.EQ",
+ arm_QADD8_NE: "QADD8.NE",
+ arm_QADD8_CS: "QADD8.CS",
+ arm_QADD8_CC: "QADD8.CC",
+ arm_QADD8_MI: "QADD8.MI",
+ arm_QADD8_PL: "QADD8.PL",
+ arm_QADD8_VS: "QADD8.VS",
+ arm_QADD8_VC: "QADD8.VC",
+ arm_QADD8_HI: "QADD8.HI",
+ arm_QADD8_LS: "QADD8.LS",
+ arm_QADD8_GE: "QADD8.GE",
+ arm_QADD8_LT: "QADD8.LT",
+ arm_QADD8_GT: "QADD8.GT",
+ arm_QADD8_LE: "QADD8.LE",
+ arm_QADD8: "QADD8",
+ arm_QADD8_ZZ: "QADD8.ZZ",
+ arm_QASX_EQ: "QASX.EQ",
+ arm_QASX_NE: "QASX.NE",
+ arm_QASX_CS: "QASX.CS",
+ arm_QASX_CC: "QASX.CC",
+ arm_QASX_MI: "QASX.MI",
+ arm_QASX_PL: "QASX.PL",
+ arm_QASX_VS: "QASX.VS",
+ arm_QASX_VC: "QASX.VC",
+ arm_QASX_HI: "QASX.HI",
+ arm_QASX_LS: "QASX.LS",
+ arm_QASX_GE: "QASX.GE",
+ arm_QASX_LT: "QASX.LT",
+ arm_QASX_GT: "QASX.GT",
+ arm_QASX_LE: "QASX.LE",
+ arm_QASX: "QASX",
+ arm_QASX_ZZ: "QASX.ZZ",
+ arm_QDADD_EQ: "QDADD.EQ",
+ arm_QDADD_NE: "QDADD.NE",
+ arm_QDADD_CS: "QDADD.CS",
+ arm_QDADD_CC: "QDADD.CC",
+ arm_QDADD_MI: "QDADD.MI",
+ arm_QDADD_PL: "QDADD.PL",
+ arm_QDADD_VS: "QDADD.VS",
+ arm_QDADD_VC: "QDADD.VC",
+ arm_QDADD_HI: "QDADD.HI",
+ arm_QDADD_LS: "QDADD.LS",
+ arm_QDADD_GE: "QDADD.GE",
+ arm_QDADD_LT: "QDADD.LT",
+ arm_QDADD_GT: "QDADD.GT",
+ arm_QDADD_LE: "QDADD.LE",
+ arm_QDADD: "QDADD",
+ arm_QDADD_ZZ: "QDADD.ZZ",
+ arm_QDSUB_EQ: "QDSUB.EQ",
+ arm_QDSUB_NE: "QDSUB.NE",
+ arm_QDSUB_CS: "QDSUB.CS",
+ arm_QDSUB_CC: "QDSUB.CC",
+ arm_QDSUB_MI: "QDSUB.MI",
+ arm_QDSUB_PL: "QDSUB.PL",
+ arm_QDSUB_VS: "QDSUB.VS",
+ arm_QDSUB_VC: "QDSUB.VC",
+ arm_QDSUB_HI: "QDSUB.HI",
+ arm_QDSUB_LS: "QDSUB.LS",
+ arm_QDSUB_GE: "QDSUB.GE",
+ arm_QDSUB_LT: "QDSUB.LT",
+ arm_QDSUB_GT: "QDSUB.GT",
+ arm_QDSUB_LE: "QDSUB.LE",
+ arm_QDSUB: "QDSUB",
+ arm_QDSUB_ZZ: "QDSUB.ZZ",
+ arm_QSAX_EQ: "QSAX.EQ",
+ arm_QSAX_NE: "QSAX.NE",
+ arm_QSAX_CS: "QSAX.CS",
+ arm_QSAX_CC: "QSAX.CC",
+ arm_QSAX_MI: "QSAX.MI",
+ arm_QSAX_PL: "QSAX.PL",
+ arm_QSAX_VS: "QSAX.VS",
+ arm_QSAX_VC: "QSAX.VC",
+ arm_QSAX_HI: "QSAX.HI",
+ arm_QSAX_LS: "QSAX.LS",
+ arm_QSAX_GE: "QSAX.GE",
+ arm_QSAX_LT: "QSAX.LT",
+ arm_QSAX_GT: "QSAX.GT",
+ arm_QSAX_LE: "QSAX.LE",
+ arm_QSAX: "QSAX",
+ arm_QSAX_ZZ: "QSAX.ZZ",
+ arm_QSUB_EQ: "QSUB.EQ",
+ arm_QSUB_NE: "QSUB.NE",
+ arm_QSUB_CS: "QSUB.CS",
+ arm_QSUB_CC: "QSUB.CC",
+ arm_QSUB_MI: "QSUB.MI",
+ arm_QSUB_PL: "QSUB.PL",
+ arm_QSUB_VS: "QSUB.VS",
+ arm_QSUB_VC: "QSUB.VC",
+ arm_QSUB_HI: "QSUB.HI",
+ arm_QSUB_LS: "QSUB.LS",
+ arm_QSUB_GE: "QSUB.GE",
+ arm_QSUB_LT: "QSUB.LT",
+ arm_QSUB_GT: "QSUB.GT",
+ arm_QSUB_LE: "QSUB.LE",
+ arm_QSUB: "QSUB",
+ arm_QSUB_ZZ: "QSUB.ZZ",
+ arm_QSUB16_EQ: "QSUB16.EQ",
+ arm_QSUB16_NE: "QSUB16.NE",
+ arm_QSUB16_CS: "QSUB16.CS",
+ arm_QSUB16_CC: "QSUB16.CC",
+ arm_QSUB16_MI: "QSUB16.MI",
+ arm_QSUB16_PL: "QSUB16.PL",
+ arm_QSUB16_VS: "QSUB16.VS",
+ arm_QSUB16_VC: "QSUB16.VC",
+ arm_QSUB16_HI: "QSUB16.HI",
+ arm_QSUB16_LS: "QSUB16.LS",
+ arm_QSUB16_GE: "QSUB16.GE",
+ arm_QSUB16_LT: "QSUB16.LT",
+ arm_QSUB16_GT: "QSUB16.GT",
+ arm_QSUB16_LE: "QSUB16.LE",
+ arm_QSUB16: "QSUB16",
+ arm_QSUB16_ZZ: "QSUB16.ZZ",
+ arm_QSUB8_EQ: "QSUB8.EQ",
+ arm_QSUB8_NE: "QSUB8.NE",
+ arm_QSUB8_CS: "QSUB8.CS",
+ arm_QSUB8_CC: "QSUB8.CC",
+ arm_QSUB8_MI: "QSUB8.MI",
+ arm_QSUB8_PL: "QSUB8.PL",
+ arm_QSUB8_VS: "QSUB8.VS",
+ arm_QSUB8_VC: "QSUB8.VC",
+ arm_QSUB8_HI: "QSUB8.HI",
+ arm_QSUB8_LS: "QSUB8.LS",
+ arm_QSUB8_GE: "QSUB8.GE",
+ arm_QSUB8_LT: "QSUB8.LT",
+ arm_QSUB8_GT: "QSUB8.GT",
+ arm_QSUB8_LE: "QSUB8.LE",
+ arm_QSUB8: "QSUB8",
+ arm_QSUB8_ZZ: "QSUB8.ZZ",
+ arm_RBIT_EQ: "RBIT.EQ",
+ arm_RBIT_NE: "RBIT.NE",
+ arm_RBIT_CS: "RBIT.CS",
+ arm_RBIT_CC: "RBIT.CC",
+ arm_RBIT_MI: "RBIT.MI",
+ arm_RBIT_PL: "RBIT.PL",
+ arm_RBIT_VS: "RBIT.VS",
+ arm_RBIT_VC: "RBIT.VC",
+ arm_RBIT_HI: "RBIT.HI",
+ arm_RBIT_LS: "RBIT.LS",
+ arm_RBIT_GE: "RBIT.GE",
+ arm_RBIT_LT: "RBIT.LT",
+ arm_RBIT_GT: "RBIT.GT",
+ arm_RBIT_LE: "RBIT.LE",
+ arm_RBIT: "RBIT",
+ arm_RBIT_ZZ: "RBIT.ZZ",
+ arm_REV_EQ: "REV.EQ",
+ arm_REV_NE: "REV.NE",
+ arm_REV_CS: "REV.CS",
+ arm_REV_CC: "REV.CC",
+ arm_REV_MI: "REV.MI",
+ arm_REV_PL: "REV.PL",
+ arm_REV_VS: "REV.VS",
+ arm_REV_VC: "REV.VC",
+ arm_REV_HI: "REV.HI",
+ arm_REV_LS: "REV.LS",
+ arm_REV_GE: "REV.GE",
+ arm_REV_LT: "REV.LT",
+ arm_REV_GT: "REV.GT",
+ arm_REV_LE: "REV.LE",
+ arm_REV: "REV",
+ arm_REV_ZZ: "REV.ZZ",
+ arm_REV16_EQ: "REV16.EQ",
+ arm_REV16_NE: "REV16.NE",
+ arm_REV16_CS: "REV16.CS",
+ arm_REV16_CC: "REV16.CC",
+ arm_REV16_MI: "REV16.MI",
+ arm_REV16_PL: "REV16.PL",
+ arm_REV16_VS: "REV16.VS",
+ arm_REV16_VC: "REV16.VC",
+ arm_REV16_HI: "REV16.HI",
+ arm_REV16_LS: "REV16.LS",
+ arm_REV16_GE: "REV16.GE",
+ arm_REV16_LT: "REV16.LT",
+ arm_REV16_GT: "REV16.GT",
+ arm_REV16_LE: "REV16.LE",
+ arm_REV16: "REV16",
+ arm_REV16_ZZ: "REV16.ZZ",
+ arm_REVSH_EQ: "REVSH.EQ",
+ arm_REVSH_NE: "REVSH.NE",
+ arm_REVSH_CS: "REVSH.CS",
+ arm_REVSH_CC: "REVSH.CC",
+ arm_REVSH_MI: "REVSH.MI",
+ arm_REVSH_PL: "REVSH.PL",
+ arm_REVSH_VS: "REVSH.VS",
+ arm_REVSH_VC: "REVSH.VC",
+ arm_REVSH_HI: "REVSH.HI",
+ arm_REVSH_LS: "REVSH.LS",
+ arm_REVSH_GE: "REVSH.GE",
+ arm_REVSH_LT: "REVSH.LT",
+ arm_REVSH_GT: "REVSH.GT",
+ arm_REVSH_LE: "REVSH.LE",
+ arm_REVSH: "REVSH",
+ arm_REVSH_ZZ: "REVSH.ZZ",
+ arm_ROR_EQ: "ROR.EQ",
+ arm_ROR_NE: "ROR.NE",
+ arm_ROR_CS: "ROR.CS",
+ arm_ROR_CC: "ROR.CC",
+ arm_ROR_MI: "ROR.MI",
+ arm_ROR_PL: "ROR.PL",
+ arm_ROR_VS: "ROR.VS",
+ arm_ROR_VC: "ROR.VC",
+ arm_ROR_HI: "ROR.HI",
+ arm_ROR_LS: "ROR.LS",
+ arm_ROR_GE: "ROR.GE",
+ arm_ROR_LT: "ROR.LT",
+ arm_ROR_GT: "ROR.GT",
+ arm_ROR_LE: "ROR.LE",
+ arm_ROR: "ROR",
+ arm_ROR_ZZ: "ROR.ZZ",
+ arm_ROR_S_EQ: "ROR.S.EQ",
+ arm_ROR_S_NE: "ROR.S.NE",
+ arm_ROR_S_CS: "ROR.S.CS",
+ arm_ROR_S_CC: "ROR.S.CC",
+ arm_ROR_S_MI: "ROR.S.MI",
+ arm_ROR_S_PL: "ROR.S.PL",
+ arm_ROR_S_VS: "ROR.S.VS",
+ arm_ROR_S_VC: "ROR.S.VC",
+ arm_ROR_S_HI: "ROR.S.HI",
+ arm_ROR_S_LS: "ROR.S.LS",
+ arm_ROR_S_GE: "ROR.S.GE",
+ arm_ROR_S_LT: "ROR.S.LT",
+ arm_ROR_S_GT: "ROR.S.GT",
+ arm_ROR_S_LE: "ROR.S.LE",
+ arm_ROR_S: "ROR.S",
+ arm_ROR_S_ZZ: "ROR.S.ZZ",
+ arm_RRX_EQ: "RRX.EQ",
+ arm_RRX_NE: "RRX.NE",
+ arm_RRX_CS: "RRX.CS",
+ arm_RRX_CC: "RRX.CC",
+ arm_RRX_MI: "RRX.MI",
+ arm_RRX_PL: "RRX.PL",
+ arm_RRX_VS: "RRX.VS",
+ arm_RRX_VC: "RRX.VC",
+ arm_RRX_HI: "RRX.HI",
+ arm_RRX_LS: "RRX.LS",
+ arm_RRX_GE: "RRX.GE",
+ arm_RRX_LT: "RRX.LT",
+ arm_RRX_GT: "RRX.GT",
+ arm_RRX_LE: "RRX.LE",
+ arm_RRX: "RRX",
+ arm_RRX_ZZ: "RRX.ZZ",
+ arm_RRX_S_EQ: "RRX.S.EQ",
+ arm_RRX_S_NE: "RRX.S.NE",
+ arm_RRX_S_CS: "RRX.S.CS",
+ arm_RRX_S_CC: "RRX.S.CC",
+ arm_RRX_S_MI: "RRX.S.MI",
+ arm_RRX_S_PL: "RRX.S.PL",
+ arm_RRX_S_VS: "RRX.S.VS",
+ arm_RRX_S_VC: "RRX.S.VC",
+ arm_RRX_S_HI: "RRX.S.HI",
+ arm_RRX_S_LS: "RRX.S.LS",
+ arm_RRX_S_GE: "RRX.S.GE",
+ arm_RRX_S_LT: "RRX.S.LT",
+ arm_RRX_S_GT: "RRX.S.GT",
+ arm_RRX_S_LE: "RRX.S.LE",
+ arm_RRX_S: "RRX.S",
+ arm_RRX_S_ZZ: "RRX.S.ZZ",
+ arm_RSB_EQ: "RSB.EQ",
+ arm_RSB_NE: "RSB.NE",
+ arm_RSB_CS: "RSB.CS",
+ arm_RSB_CC: "RSB.CC",
+ arm_RSB_MI: "RSB.MI",
+ arm_RSB_PL: "RSB.PL",
+ arm_RSB_VS: "RSB.VS",
+ arm_RSB_VC: "RSB.VC",
+ arm_RSB_HI: "RSB.HI",
+ arm_RSB_LS: "RSB.LS",
+ arm_RSB_GE: "RSB.GE",
+ arm_RSB_LT: "RSB.LT",
+ arm_RSB_GT: "RSB.GT",
+ arm_RSB_LE: "RSB.LE",
+ arm_RSB: "RSB",
+ arm_RSB_ZZ: "RSB.ZZ",
+ arm_RSB_S_EQ: "RSB.S.EQ",
+ arm_RSB_S_NE: "RSB.S.NE",
+ arm_RSB_S_CS: "RSB.S.CS",
+ arm_RSB_S_CC: "RSB.S.CC",
+ arm_RSB_S_MI: "RSB.S.MI",
+ arm_RSB_S_PL: "RSB.S.PL",
+ arm_RSB_S_VS: "RSB.S.VS",
+ arm_RSB_S_VC: "RSB.S.VC",
+ arm_RSB_S_HI: "RSB.S.HI",
+ arm_RSB_S_LS: "RSB.S.LS",
+ arm_RSB_S_GE: "RSB.S.GE",
+ arm_RSB_S_LT: "RSB.S.LT",
+ arm_RSB_S_GT: "RSB.S.GT",
+ arm_RSB_S_LE: "RSB.S.LE",
+ arm_RSB_S: "RSB.S",
+ arm_RSB_S_ZZ: "RSB.S.ZZ",
+ arm_RSC_EQ: "RSC.EQ",
+ arm_RSC_NE: "RSC.NE",
+ arm_RSC_CS: "RSC.CS",
+ arm_RSC_CC: "RSC.CC",
+ arm_RSC_MI: "RSC.MI",
+ arm_RSC_PL: "RSC.PL",
+ arm_RSC_VS: "RSC.VS",
+ arm_RSC_VC: "RSC.VC",
+ arm_RSC_HI: "RSC.HI",
+ arm_RSC_LS: "RSC.LS",
+ arm_RSC_GE: "RSC.GE",
+ arm_RSC_LT: "RSC.LT",
+ arm_RSC_GT: "RSC.GT",
+ arm_RSC_LE: "RSC.LE",
+ arm_RSC: "RSC",
+ arm_RSC_ZZ: "RSC.ZZ",
+ arm_RSC_S_EQ: "RSC.S.EQ",
+ arm_RSC_S_NE: "RSC.S.NE",
+ arm_RSC_S_CS: "RSC.S.CS",
+ arm_RSC_S_CC: "RSC.S.CC",
+ arm_RSC_S_MI: "RSC.S.MI",
+ arm_RSC_S_PL: "RSC.S.PL",
+ arm_RSC_S_VS: "RSC.S.VS",
+ arm_RSC_S_VC: "RSC.S.VC",
+ arm_RSC_S_HI: "RSC.S.HI",
+ arm_RSC_S_LS: "RSC.S.LS",
+ arm_RSC_S_GE: "RSC.S.GE",
+ arm_RSC_S_LT: "RSC.S.LT",
+ arm_RSC_S_GT: "RSC.S.GT",
+ arm_RSC_S_LE: "RSC.S.LE",
+ arm_RSC_S: "RSC.S",
+ arm_RSC_S_ZZ: "RSC.S.ZZ",
+ arm_SADD16_EQ: "SADD16.EQ",
+ arm_SADD16_NE: "SADD16.NE",
+ arm_SADD16_CS: "SADD16.CS",
+ arm_SADD16_CC: "SADD16.CC",
+ arm_SADD16_MI: "SADD16.MI",
+ arm_SADD16_PL: "SADD16.PL",
+ arm_SADD16_VS: "SADD16.VS",
+ arm_SADD16_VC: "SADD16.VC",
+ arm_SADD16_HI: "SADD16.HI",
+ arm_SADD16_LS: "SADD16.LS",
+ arm_SADD16_GE: "SADD16.GE",
+ arm_SADD16_LT: "SADD16.LT",
+ arm_SADD16_GT: "SADD16.GT",
+ arm_SADD16_LE: "SADD16.LE",
+ arm_SADD16: "SADD16",
+ arm_SADD16_ZZ: "SADD16.ZZ",
+ arm_SADD8_EQ: "SADD8.EQ",
+ arm_SADD8_NE: "SADD8.NE",
+ arm_SADD8_CS: "SADD8.CS",
+ arm_SADD8_CC: "SADD8.CC",
+ arm_SADD8_MI: "SADD8.MI",
+ arm_SADD8_PL: "SADD8.PL",
+ arm_SADD8_VS: "SADD8.VS",
+ arm_SADD8_VC: "SADD8.VC",
+ arm_SADD8_HI: "SADD8.HI",
+ arm_SADD8_LS: "SADD8.LS",
+ arm_SADD8_GE: "SADD8.GE",
+ arm_SADD8_LT: "SADD8.LT",
+ arm_SADD8_GT: "SADD8.GT",
+ arm_SADD8_LE: "SADD8.LE",
+ arm_SADD8: "SADD8",
+ arm_SADD8_ZZ: "SADD8.ZZ",
+ arm_SASX_EQ: "SASX.EQ",
+ arm_SASX_NE: "SASX.NE",
+ arm_SASX_CS: "SASX.CS",
+ arm_SASX_CC: "SASX.CC",
+ arm_SASX_MI: "SASX.MI",
+ arm_SASX_PL: "SASX.PL",
+ arm_SASX_VS: "SASX.VS",
+ arm_SASX_VC: "SASX.VC",
+ arm_SASX_HI: "SASX.HI",
+ arm_SASX_LS: "SASX.LS",
+ arm_SASX_GE: "SASX.GE",
+ arm_SASX_LT: "SASX.LT",
+ arm_SASX_GT: "SASX.GT",
+ arm_SASX_LE: "SASX.LE",
+ arm_SASX: "SASX",
+ arm_SASX_ZZ: "SASX.ZZ",
+ arm_SBC_EQ: "SBC.EQ",
+ arm_SBC_NE: "SBC.NE",
+ arm_SBC_CS: "SBC.CS",
+ arm_SBC_CC: "SBC.CC",
+ arm_SBC_MI: "SBC.MI",
+ arm_SBC_PL: "SBC.PL",
+ arm_SBC_VS: "SBC.VS",
+ arm_SBC_VC: "SBC.VC",
+ arm_SBC_HI: "SBC.HI",
+ arm_SBC_LS: "SBC.LS",
+ arm_SBC_GE: "SBC.GE",
+ arm_SBC_LT: "SBC.LT",
+ arm_SBC_GT: "SBC.GT",
+ arm_SBC_LE: "SBC.LE",
+ arm_SBC: "SBC",
+ arm_SBC_ZZ: "SBC.ZZ",
+ arm_SBC_S_EQ: "SBC.S.EQ",
+ arm_SBC_S_NE: "SBC.S.NE",
+ arm_SBC_S_CS: "SBC.S.CS",
+ arm_SBC_S_CC: "SBC.S.CC",
+ arm_SBC_S_MI: "SBC.S.MI",
+ arm_SBC_S_PL: "SBC.S.PL",
+ arm_SBC_S_VS: "SBC.S.VS",
+ arm_SBC_S_VC: "SBC.S.VC",
+ arm_SBC_S_HI: "SBC.S.HI",
+ arm_SBC_S_LS: "SBC.S.LS",
+ arm_SBC_S_GE: "SBC.S.GE",
+ arm_SBC_S_LT: "SBC.S.LT",
+ arm_SBC_S_GT: "SBC.S.GT",
+ arm_SBC_S_LE: "SBC.S.LE",
+ arm_SBC_S: "SBC.S",
+ arm_SBC_S_ZZ: "SBC.S.ZZ",
+ arm_SBFX_EQ: "SBFX.EQ",
+ arm_SBFX_NE: "SBFX.NE",
+ arm_SBFX_CS: "SBFX.CS",
+ arm_SBFX_CC: "SBFX.CC",
+ arm_SBFX_MI: "SBFX.MI",
+ arm_SBFX_PL: "SBFX.PL",
+ arm_SBFX_VS: "SBFX.VS",
+ arm_SBFX_VC: "SBFX.VC",
+ arm_SBFX_HI: "SBFX.HI",
+ arm_SBFX_LS: "SBFX.LS",
+ arm_SBFX_GE: "SBFX.GE",
+ arm_SBFX_LT: "SBFX.LT",
+ arm_SBFX_GT: "SBFX.GT",
+ arm_SBFX_LE: "SBFX.LE",
+ arm_SBFX: "SBFX",
+ arm_SBFX_ZZ: "SBFX.ZZ",
+ arm_SEL_EQ: "SEL.EQ",
+ arm_SEL_NE: "SEL.NE",
+ arm_SEL_CS: "SEL.CS",
+ arm_SEL_CC: "SEL.CC",
+ arm_SEL_MI: "SEL.MI",
+ arm_SEL_PL: "SEL.PL",
+ arm_SEL_VS: "SEL.VS",
+ arm_SEL_VC: "SEL.VC",
+ arm_SEL_HI: "SEL.HI",
+ arm_SEL_LS: "SEL.LS",
+ arm_SEL_GE: "SEL.GE",
+ arm_SEL_LT: "SEL.LT",
+ arm_SEL_GT: "SEL.GT",
+ arm_SEL_LE: "SEL.LE",
+ arm_SEL: "SEL",
+ arm_SEL_ZZ: "SEL.ZZ",
+ arm_SETEND: "SETEND",
+ arm_SEV_EQ: "SEV.EQ",
+ arm_SEV_NE: "SEV.NE",
+ arm_SEV_CS: "SEV.CS",
+ arm_SEV_CC: "SEV.CC",
+ arm_SEV_MI: "SEV.MI",
+ arm_SEV_PL: "SEV.PL",
+ arm_SEV_VS: "SEV.VS",
+ arm_SEV_VC: "SEV.VC",
+ arm_SEV_HI: "SEV.HI",
+ arm_SEV_LS: "SEV.LS",
+ arm_SEV_GE: "SEV.GE",
+ arm_SEV_LT: "SEV.LT",
+ arm_SEV_GT: "SEV.GT",
+ arm_SEV_LE: "SEV.LE",
+ arm_SEV: "SEV",
+ arm_SEV_ZZ: "SEV.ZZ",
+ arm_SHADD16_EQ: "SHADD16.EQ",
+ arm_SHADD16_NE: "SHADD16.NE",
+ arm_SHADD16_CS: "SHADD16.CS",
+ arm_SHADD16_CC: "SHADD16.CC",
+ arm_SHADD16_MI: "SHADD16.MI",
+ arm_SHADD16_PL: "SHADD16.PL",
+ arm_SHADD16_VS: "SHADD16.VS",
+ arm_SHADD16_VC: "SHADD16.VC",
+ arm_SHADD16_HI: "SHADD16.HI",
+ arm_SHADD16_LS: "SHADD16.LS",
+ arm_SHADD16_GE: "SHADD16.GE",
+ arm_SHADD16_LT: "SHADD16.LT",
+ arm_SHADD16_GT: "SHADD16.GT",
+ arm_SHADD16_LE: "SHADD16.LE",
+ arm_SHADD16: "SHADD16",
+ arm_SHADD16_ZZ: "SHADD16.ZZ",
+ arm_SHADD8_EQ: "SHADD8.EQ",
+ arm_SHADD8_NE: "SHADD8.NE",
+ arm_SHADD8_CS: "SHADD8.CS",
+ arm_SHADD8_CC: "SHADD8.CC",
+ arm_SHADD8_MI: "SHADD8.MI",
+ arm_SHADD8_PL: "SHADD8.PL",
+ arm_SHADD8_VS: "SHADD8.VS",
+ arm_SHADD8_VC: "SHADD8.VC",
+ arm_SHADD8_HI: "SHADD8.HI",
+ arm_SHADD8_LS: "SHADD8.LS",
+ arm_SHADD8_GE: "SHADD8.GE",
+ arm_SHADD8_LT: "SHADD8.LT",
+ arm_SHADD8_GT: "SHADD8.GT",
+ arm_SHADD8_LE: "SHADD8.LE",
+ arm_SHADD8: "SHADD8",
+ arm_SHADD8_ZZ: "SHADD8.ZZ",
+ arm_SHASX_EQ: "SHASX.EQ",
+ arm_SHASX_NE: "SHASX.NE",
+ arm_SHASX_CS: "SHASX.CS",
+ arm_SHASX_CC: "SHASX.CC",
+ arm_SHASX_MI: "SHASX.MI",
+ arm_SHASX_PL: "SHASX.PL",
+ arm_SHASX_VS: "SHASX.VS",
+ arm_SHASX_VC: "SHASX.VC",
+ arm_SHASX_HI: "SHASX.HI",
+ arm_SHASX_LS: "SHASX.LS",
+ arm_SHASX_GE: "SHASX.GE",
+ arm_SHASX_LT: "SHASX.LT",
+ arm_SHASX_GT: "SHASX.GT",
+ arm_SHASX_LE: "SHASX.LE",
+ arm_SHASX: "SHASX",
+ arm_SHASX_ZZ: "SHASX.ZZ",
+ arm_SHSAX_EQ: "SHSAX.EQ",
+ arm_SHSAX_NE: "SHSAX.NE",
+ arm_SHSAX_CS: "SHSAX.CS",
+ arm_SHSAX_CC: "SHSAX.CC",
+ arm_SHSAX_MI: "SHSAX.MI",
+ arm_SHSAX_PL: "SHSAX.PL",
+ arm_SHSAX_VS: "SHSAX.VS",
+ arm_SHSAX_VC: "SHSAX.VC",
+ arm_SHSAX_HI: "SHSAX.HI",
+ arm_SHSAX_LS: "SHSAX.LS",
+ arm_SHSAX_GE: "SHSAX.GE",
+ arm_SHSAX_LT: "SHSAX.LT",
+ arm_SHSAX_GT: "SHSAX.GT",
+ arm_SHSAX_LE: "SHSAX.LE",
+ arm_SHSAX: "SHSAX",
+ arm_SHSAX_ZZ: "SHSAX.ZZ",
+ arm_SHSUB16_EQ: "SHSUB16.EQ",
+ arm_SHSUB16_NE: "SHSUB16.NE",
+ arm_SHSUB16_CS: "SHSUB16.CS",
+ arm_SHSUB16_CC: "SHSUB16.CC",
+ arm_SHSUB16_MI: "SHSUB16.MI",
+ arm_SHSUB16_PL: "SHSUB16.PL",
+ arm_SHSUB16_VS: "SHSUB16.VS",
+ arm_SHSUB16_VC: "SHSUB16.VC",
+ arm_SHSUB16_HI: "SHSUB16.HI",
+ arm_SHSUB16_LS: "SHSUB16.LS",
+ arm_SHSUB16_GE: "SHSUB16.GE",
+ arm_SHSUB16_LT: "SHSUB16.LT",
+ arm_SHSUB16_GT: "SHSUB16.GT",
+ arm_SHSUB16_LE: "SHSUB16.LE",
+ arm_SHSUB16: "SHSUB16",
+ arm_SHSUB16_ZZ: "SHSUB16.ZZ",
+ arm_SHSUB8_EQ: "SHSUB8.EQ",
+ arm_SHSUB8_NE: "SHSUB8.NE",
+ arm_SHSUB8_CS: "SHSUB8.CS",
+ arm_SHSUB8_CC: "SHSUB8.CC",
+ arm_SHSUB8_MI: "SHSUB8.MI",
+ arm_SHSUB8_PL: "SHSUB8.PL",
+ arm_SHSUB8_VS: "SHSUB8.VS",
+ arm_SHSUB8_VC: "SHSUB8.VC",
+ arm_SHSUB8_HI: "SHSUB8.HI",
+ arm_SHSUB8_LS: "SHSUB8.LS",
+ arm_SHSUB8_GE: "SHSUB8.GE",
+ arm_SHSUB8_LT: "SHSUB8.LT",
+ arm_SHSUB8_GT: "SHSUB8.GT",
+ arm_SHSUB8_LE: "SHSUB8.LE",
+ arm_SHSUB8: "SHSUB8",
+ arm_SHSUB8_ZZ: "SHSUB8.ZZ",
+ arm_SMLABB_EQ: "SMLABB.EQ",
+ arm_SMLABB_NE: "SMLABB.NE",
+ arm_SMLABB_CS: "SMLABB.CS",
+ arm_SMLABB_CC: "SMLABB.CC",
+ arm_SMLABB_MI: "SMLABB.MI",
+ arm_SMLABB_PL: "SMLABB.PL",
+ arm_SMLABB_VS: "SMLABB.VS",
+ arm_SMLABB_VC: "SMLABB.VC",
+ arm_SMLABB_HI: "SMLABB.HI",
+ arm_SMLABB_LS: "SMLABB.LS",
+ arm_SMLABB_GE: "SMLABB.GE",
+ arm_SMLABB_LT: "SMLABB.LT",
+ arm_SMLABB_GT: "SMLABB.GT",
+ arm_SMLABB_LE: "SMLABB.LE",
+ arm_SMLABB: "SMLABB",
+ arm_SMLABB_ZZ: "SMLABB.ZZ",
+ arm_SMLABT_EQ: "SMLABT.EQ",
+ arm_SMLABT_NE: "SMLABT.NE",
+ arm_SMLABT_CS: "SMLABT.CS",
+ arm_SMLABT_CC: "SMLABT.CC",
+ arm_SMLABT_MI: "SMLABT.MI",
+ arm_SMLABT_PL: "SMLABT.PL",
+ arm_SMLABT_VS: "SMLABT.VS",
+ arm_SMLABT_VC: "SMLABT.VC",
+ arm_SMLABT_HI: "SMLABT.HI",
+ arm_SMLABT_LS: "SMLABT.LS",
+ arm_SMLABT_GE: "SMLABT.GE",
+ arm_SMLABT_LT: "SMLABT.LT",
+ arm_SMLABT_GT: "SMLABT.GT",
+ arm_SMLABT_LE: "SMLABT.LE",
+ arm_SMLABT: "SMLABT",
+ arm_SMLABT_ZZ: "SMLABT.ZZ",
+ arm_SMLATB_EQ: "SMLATB.EQ",
+ arm_SMLATB_NE: "SMLATB.NE",
+ arm_SMLATB_CS: "SMLATB.CS",
+ arm_SMLATB_CC: "SMLATB.CC",
+ arm_SMLATB_MI: "SMLATB.MI",
+ arm_SMLATB_PL: "SMLATB.PL",
+ arm_SMLATB_VS: "SMLATB.VS",
+ arm_SMLATB_VC: "SMLATB.VC",
+ arm_SMLATB_HI: "SMLATB.HI",
+ arm_SMLATB_LS: "SMLATB.LS",
+ arm_SMLATB_GE: "SMLATB.GE",
+ arm_SMLATB_LT: "SMLATB.LT",
+ arm_SMLATB_GT: "SMLATB.GT",
+ arm_SMLATB_LE: "SMLATB.LE",
+ arm_SMLATB: "SMLATB",
+ arm_SMLATB_ZZ: "SMLATB.ZZ",
+ arm_SMLATT_EQ: "SMLATT.EQ",
+ arm_SMLATT_NE: "SMLATT.NE",
+ arm_SMLATT_CS: "SMLATT.CS",
+ arm_SMLATT_CC: "SMLATT.CC",
+ arm_SMLATT_MI: "SMLATT.MI",
+ arm_SMLATT_PL: "SMLATT.PL",
+ arm_SMLATT_VS: "SMLATT.VS",
+ arm_SMLATT_VC: "SMLATT.VC",
+ arm_SMLATT_HI: "SMLATT.HI",
+ arm_SMLATT_LS: "SMLATT.LS",
+ arm_SMLATT_GE: "SMLATT.GE",
+ arm_SMLATT_LT: "SMLATT.LT",
+ arm_SMLATT_GT: "SMLATT.GT",
+ arm_SMLATT_LE: "SMLATT.LE",
+ arm_SMLATT: "SMLATT",
+ arm_SMLATT_ZZ: "SMLATT.ZZ",
+ arm_SMLAD_EQ: "SMLAD.EQ",
+ arm_SMLAD_NE: "SMLAD.NE",
+ arm_SMLAD_CS: "SMLAD.CS",
+ arm_SMLAD_CC: "SMLAD.CC",
+ arm_SMLAD_MI: "SMLAD.MI",
+ arm_SMLAD_PL: "SMLAD.PL",
+ arm_SMLAD_VS: "SMLAD.VS",
+ arm_SMLAD_VC: "SMLAD.VC",
+ arm_SMLAD_HI: "SMLAD.HI",
+ arm_SMLAD_LS: "SMLAD.LS",
+ arm_SMLAD_GE: "SMLAD.GE",
+ arm_SMLAD_LT: "SMLAD.LT",
+ arm_SMLAD_GT: "SMLAD.GT",
+ arm_SMLAD_LE: "SMLAD.LE",
+ arm_SMLAD: "SMLAD",
+ arm_SMLAD_ZZ: "SMLAD.ZZ",
+ arm_SMLAD_X_EQ: "SMLAD.X.EQ",
+ arm_SMLAD_X_NE: "SMLAD.X.NE",
+ arm_SMLAD_X_CS: "SMLAD.X.CS",
+ arm_SMLAD_X_CC: "SMLAD.X.CC",
+ arm_SMLAD_X_MI: "SMLAD.X.MI",
+ arm_SMLAD_X_PL: "SMLAD.X.PL",
+ arm_SMLAD_X_VS: "SMLAD.X.VS",
+ arm_SMLAD_X_VC: "SMLAD.X.VC",
+ arm_SMLAD_X_HI: "SMLAD.X.HI",
+ arm_SMLAD_X_LS: "SMLAD.X.LS",
+ arm_SMLAD_X_GE: "SMLAD.X.GE",
+ arm_SMLAD_X_LT: "SMLAD.X.LT",
+ arm_SMLAD_X_GT: "SMLAD.X.GT",
+ arm_SMLAD_X_LE: "SMLAD.X.LE",
+ arm_SMLAD_X: "SMLAD.X",
+ arm_SMLAD_X_ZZ: "SMLAD.X.ZZ",
+ arm_SMLAL_EQ: "SMLAL.EQ",
+ arm_SMLAL_NE: "SMLAL.NE",
+ arm_SMLAL_CS: "SMLAL.CS",
+ arm_SMLAL_CC: "SMLAL.CC",
+ arm_SMLAL_MI: "SMLAL.MI",
+ arm_SMLAL_PL: "SMLAL.PL",
+ arm_SMLAL_VS: "SMLAL.VS",
+ arm_SMLAL_VC: "SMLAL.VC",
+ arm_SMLAL_HI: "SMLAL.HI",
+ arm_SMLAL_LS: "SMLAL.LS",
+ arm_SMLAL_GE: "SMLAL.GE",
+ arm_SMLAL_LT: "SMLAL.LT",
+ arm_SMLAL_GT: "SMLAL.GT",
+ arm_SMLAL_LE: "SMLAL.LE",
+ arm_SMLAL: "SMLAL",
+ arm_SMLAL_ZZ: "SMLAL.ZZ",
+ arm_SMLAL_S_EQ: "SMLAL.S.EQ",
+ arm_SMLAL_S_NE: "SMLAL.S.NE",
+ arm_SMLAL_S_CS: "SMLAL.S.CS",
+ arm_SMLAL_S_CC: "SMLAL.S.CC",
+ arm_SMLAL_S_MI: "SMLAL.S.MI",
+ arm_SMLAL_S_PL: "SMLAL.S.PL",
+ arm_SMLAL_S_VS: "SMLAL.S.VS",
+ arm_SMLAL_S_VC: "SMLAL.S.VC",
+ arm_SMLAL_S_HI: "SMLAL.S.HI",
+ arm_SMLAL_S_LS: "SMLAL.S.LS",
+ arm_SMLAL_S_GE: "SMLAL.S.GE",
+ arm_SMLAL_S_LT: "SMLAL.S.LT",
+ arm_SMLAL_S_GT: "SMLAL.S.GT",
+ arm_SMLAL_S_LE: "SMLAL.S.LE",
+ arm_SMLAL_S: "SMLAL.S",
+ arm_SMLAL_S_ZZ: "SMLAL.S.ZZ",
+ arm_SMLALBB_EQ: "SMLALBB.EQ",
+ arm_SMLALBB_NE: "SMLALBB.NE",
+ arm_SMLALBB_CS: "SMLALBB.CS",
+ arm_SMLALBB_CC: "SMLALBB.CC",
+ arm_SMLALBB_MI: "SMLALBB.MI",
+ arm_SMLALBB_PL: "SMLALBB.PL",
+ arm_SMLALBB_VS: "SMLALBB.VS",
+ arm_SMLALBB_VC: "SMLALBB.VC",
+ arm_SMLALBB_HI: "SMLALBB.HI",
+ arm_SMLALBB_LS: "SMLALBB.LS",
+ arm_SMLALBB_GE: "SMLALBB.GE",
+ arm_SMLALBB_LT: "SMLALBB.LT",
+ arm_SMLALBB_GT: "SMLALBB.GT",
+ arm_SMLALBB_LE: "SMLALBB.LE",
+ arm_SMLALBB: "SMLALBB",
+ arm_SMLALBB_ZZ: "SMLALBB.ZZ",
+ arm_SMLALBT_EQ: "SMLALBT.EQ",
+ arm_SMLALBT_NE: "SMLALBT.NE",
+ arm_SMLALBT_CS: "SMLALBT.CS",
+ arm_SMLALBT_CC: "SMLALBT.CC",
+ arm_SMLALBT_MI: "SMLALBT.MI",
+ arm_SMLALBT_PL: "SMLALBT.PL",
+ arm_SMLALBT_VS: "SMLALBT.VS",
+ arm_SMLALBT_VC: "SMLALBT.VC",
+ arm_SMLALBT_HI: "SMLALBT.HI",
+ arm_SMLALBT_LS: "SMLALBT.LS",
+ arm_SMLALBT_GE: "SMLALBT.GE",
+ arm_SMLALBT_LT: "SMLALBT.LT",
+ arm_SMLALBT_GT: "SMLALBT.GT",
+ arm_SMLALBT_LE: "SMLALBT.LE",
+ arm_SMLALBT: "SMLALBT",
+ arm_SMLALBT_ZZ: "SMLALBT.ZZ",
+ arm_SMLALTB_EQ: "SMLALTB.EQ",
+ arm_SMLALTB_NE: "SMLALTB.NE",
+ arm_SMLALTB_CS: "SMLALTB.CS",
+ arm_SMLALTB_CC: "SMLALTB.CC",
+ arm_SMLALTB_MI: "SMLALTB.MI",
+ arm_SMLALTB_PL: "SMLALTB.PL",
+ arm_SMLALTB_VS: "SMLALTB.VS",
+ arm_SMLALTB_VC: "SMLALTB.VC",
+ arm_SMLALTB_HI: "SMLALTB.HI",
+ arm_SMLALTB_LS: "SMLALTB.LS",
+ arm_SMLALTB_GE: "SMLALTB.GE",
+ arm_SMLALTB_LT: "SMLALTB.LT",
+ arm_SMLALTB_GT: "SMLALTB.GT",
+ arm_SMLALTB_LE: "SMLALTB.LE",
+ arm_SMLALTB: "SMLALTB",
+ arm_SMLALTB_ZZ: "SMLALTB.ZZ",
+ arm_SMLALTT_EQ: "SMLALTT.EQ",
+ arm_SMLALTT_NE: "SMLALTT.NE",
+ arm_SMLALTT_CS: "SMLALTT.CS",
+ arm_SMLALTT_CC: "SMLALTT.CC",
+ arm_SMLALTT_MI: "SMLALTT.MI",
+ arm_SMLALTT_PL: "SMLALTT.PL",
+ arm_SMLALTT_VS: "SMLALTT.VS",
+ arm_SMLALTT_VC: "SMLALTT.VC",
+ arm_SMLALTT_HI: "SMLALTT.HI",
+ arm_SMLALTT_LS: "SMLALTT.LS",
+ arm_SMLALTT_GE: "SMLALTT.GE",
+ arm_SMLALTT_LT: "SMLALTT.LT",
+ arm_SMLALTT_GT: "SMLALTT.GT",
+ arm_SMLALTT_LE: "SMLALTT.LE",
+ arm_SMLALTT: "SMLALTT",
+ arm_SMLALTT_ZZ: "SMLALTT.ZZ",
+ arm_SMLALD_EQ: "SMLALD.EQ",
+ arm_SMLALD_NE: "SMLALD.NE",
+ arm_SMLALD_CS: "SMLALD.CS",
+ arm_SMLALD_CC: "SMLALD.CC",
+ arm_SMLALD_MI: "SMLALD.MI",
+ arm_SMLALD_PL: "SMLALD.PL",
+ arm_SMLALD_VS: "SMLALD.VS",
+ arm_SMLALD_VC: "SMLALD.VC",
+ arm_SMLALD_HI: "SMLALD.HI",
+ arm_SMLALD_LS: "SMLALD.LS",
+ arm_SMLALD_GE: "SMLALD.GE",
+ arm_SMLALD_LT: "SMLALD.LT",
+ arm_SMLALD_GT: "SMLALD.GT",
+ arm_SMLALD_LE: "SMLALD.LE",
+ arm_SMLALD: "SMLALD",
+ arm_SMLALD_ZZ: "SMLALD.ZZ",
+ arm_SMLALD_X_EQ: "SMLALD.X.EQ",
+ arm_SMLALD_X_NE: "SMLALD.X.NE",
+ arm_SMLALD_X_CS: "SMLALD.X.CS",
+ arm_SMLALD_X_CC: "SMLALD.X.CC",
+ arm_SMLALD_X_MI: "SMLALD.X.MI",
+ arm_SMLALD_X_PL: "SMLALD.X.PL",
+ arm_SMLALD_X_VS: "SMLALD.X.VS",
+ arm_SMLALD_X_VC: "SMLALD.X.VC",
+ arm_SMLALD_X_HI: "SMLALD.X.HI",
+ arm_SMLALD_X_LS: "SMLALD.X.LS",
+ arm_SMLALD_X_GE: "SMLALD.X.GE",
+ arm_SMLALD_X_LT: "SMLALD.X.LT",
+ arm_SMLALD_X_GT: "SMLALD.X.GT",
+ arm_SMLALD_X_LE: "SMLALD.X.LE",
+ arm_SMLALD_X: "SMLALD.X",
+ arm_SMLALD_X_ZZ: "SMLALD.X.ZZ",
+ arm_SMLAWB_EQ: "SMLAWB.EQ",
+ arm_SMLAWB_NE: "SMLAWB.NE",
+ arm_SMLAWB_CS: "SMLAWB.CS",
+ arm_SMLAWB_CC: "SMLAWB.CC",
+ arm_SMLAWB_MI: "SMLAWB.MI",
+ arm_SMLAWB_PL: "SMLAWB.PL",
+ arm_SMLAWB_VS: "SMLAWB.VS",
+ arm_SMLAWB_VC: "SMLAWB.VC",
+ arm_SMLAWB_HI: "SMLAWB.HI",
+ arm_SMLAWB_LS: "SMLAWB.LS",
+ arm_SMLAWB_GE: "SMLAWB.GE",
+ arm_SMLAWB_LT: "SMLAWB.LT",
+ arm_SMLAWB_GT: "SMLAWB.GT",
+ arm_SMLAWB_LE: "SMLAWB.LE",
+ arm_SMLAWB: "SMLAWB",
+ arm_SMLAWB_ZZ: "SMLAWB.ZZ",
+ arm_SMLAWT_EQ: "SMLAWT.EQ",
+ arm_SMLAWT_NE: "SMLAWT.NE",
+ arm_SMLAWT_CS: "SMLAWT.CS",
+ arm_SMLAWT_CC: "SMLAWT.CC",
+ arm_SMLAWT_MI: "SMLAWT.MI",
+ arm_SMLAWT_PL: "SMLAWT.PL",
+ arm_SMLAWT_VS: "SMLAWT.VS",
+ arm_SMLAWT_VC: "SMLAWT.VC",
+ arm_SMLAWT_HI: "SMLAWT.HI",
+ arm_SMLAWT_LS: "SMLAWT.LS",
+ arm_SMLAWT_GE: "SMLAWT.GE",
+ arm_SMLAWT_LT: "SMLAWT.LT",
+ arm_SMLAWT_GT: "SMLAWT.GT",
+ arm_SMLAWT_LE: "SMLAWT.LE",
+ arm_SMLAWT: "SMLAWT",
+ arm_SMLAWT_ZZ: "SMLAWT.ZZ",
+ arm_SMLSD_EQ: "SMLSD.EQ",
+ arm_SMLSD_NE: "SMLSD.NE",
+ arm_SMLSD_CS: "SMLSD.CS",
+ arm_SMLSD_CC: "SMLSD.CC",
+ arm_SMLSD_MI: "SMLSD.MI",
+ arm_SMLSD_PL: "SMLSD.PL",
+ arm_SMLSD_VS: "SMLSD.VS",
+ arm_SMLSD_VC: "SMLSD.VC",
+ arm_SMLSD_HI: "SMLSD.HI",
+ arm_SMLSD_LS: "SMLSD.LS",
+ arm_SMLSD_GE: "SMLSD.GE",
+ arm_SMLSD_LT: "SMLSD.LT",
+ arm_SMLSD_GT: "SMLSD.GT",
+ arm_SMLSD_LE: "SMLSD.LE",
+ arm_SMLSD: "SMLSD",
+ arm_SMLSD_ZZ: "SMLSD.ZZ",
+ arm_SMLSD_X_EQ: "SMLSD.X.EQ",
+ arm_SMLSD_X_NE: "SMLSD.X.NE",
+ arm_SMLSD_X_CS: "SMLSD.X.CS",
+ arm_SMLSD_X_CC: "SMLSD.X.CC",
+ arm_SMLSD_X_MI: "SMLSD.X.MI",
+ arm_SMLSD_X_PL: "SMLSD.X.PL",
+ arm_SMLSD_X_VS: "SMLSD.X.VS",
+ arm_SMLSD_X_VC: "SMLSD.X.VC",
+ arm_SMLSD_X_HI: "SMLSD.X.HI",
+ arm_SMLSD_X_LS: "SMLSD.X.LS",
+ arm_SMLSD_X_GE: "SMLSD.X.GE",
+ arm_SMLSD_X_LT: "SMLSD.X.LT",
+ arm_SMLSD_X_GT: "SMLSD.X.GT",
+ arm_SMLSD_X_LE: "SMLSD.X.LE",
+ arm_SMLSD_X: "SMLSD.X",
+ arm_SMLSD_X_ZZ: "SMLSD.X.ZZ",
+ arm_SMLSLD_EQ: "SMLSLD.EQ",
+ arm_SMLSLD_NE: "SMLSLD.NE",
+ arm_SMLSLD_CS: "SMLSLD.CS",
+ arm_SMLSLD_CC: "SMLSLD.CC",
+ arm_SMLSLD_MI: "SMLSLD.MI",
+ arm_SMLSLD_PL: "SMLSLD.PL",
+ arm_SMLSLD_VS: "SMLSLD.VS",
+ arm_SMLSLD_VC: "SMLSLD.VC",
+ arm_SMLSLD_HI: "SMLSLD.HI",
+ arm_SMLSLD_LS: "SMLSLD.LS",
+ arm_SMLSLD_GE: "SMLSLD.GE",
+ arm_SMLSLD_LT: "SMLSLD.LT",
+ arm_SMLSLD_GT: "SMLSLD.GT",
+ arm_SMLSLD_LE: "SMLSLD.LE",
+ arm_SMLSLD: "SMLSLD",
+ arm_SMLSLD_ZZ: "SMLSLD.ZZ",
+ arm_SMLSLD_X_EQ: "SMLSLD.X.EQ",
+ arm_SMLSLD_X_NE: "SMLSLD.X.NE",
+ arm_SMLSLD_X_CS: "SMLSLD.X.CS",
+ arm_SMLSLD_X_CC: "SMLSLD.X.CC",
+ arm_SMLSLD_X_MI: "SMLSLD.X.MI",
+ arm_SMLSLD_X_PL: "SMLSLD.X.PL",
+ arm_SMLSLD_X_VS: "SMLSLD.X.VS",
+ arm_SMLSLD_X_VC: "SMLSLD.X.VC",
+ arm_SMLSLD_X_HI: "SMLSLD.X.HI",
+ arm_SMLSLD_X_LS: "SMLSLD.X.LS",
+ arm_SMLSLD_X_GE: "SMLSLD.X.GE",
+ arm_SMLSLD_X_LT: "SMLSLD.X.LT",
+ arm_SMLSLD_X_GT: "SMLSLD.X.GT",
+ arm_SMLSLD_X_LE: "SMLSLD.X.LE",
+ arm_SMLSLD_X: "SMLSLD.X",
+ arm_SMLSLD_X_ZZ: "SMLSLD.X.ZZ",
+ arm_SMMLA_EQ: "SMMLA.EQ",
+ arm_SMMLA_NE: "SMMLA.NE",
+ arm_SMMLA_CS: "SMMLA.CS",
+ arm_SMMLA_CC: "SMMLA.CC",
+ arm_SMMLA_MI: "SMMLA.MI",
+ arm_SMMLA_PL: "SMMLA.PL",
+ arm_SMMLA_VS: "SMMLA.VS",
+ arm_SMMLA_VC: "SMMLA.VC",
+ arm_SMMLA_HI: "SMMLA.HI",
+ arm_SMMLA_LS: "SMMLA.LS",
+ arm_SMMLA_GE: "SMMLA.GE",
+ arm_SMMLA_LT: "SMMLA.LT",
+ arm_SMMLA_GT: "SMMLA.GT",
+ arm_SMMLA_LE: "SMMLA.LE",
+ arm_SMMLA: "SMMLA",
+ arm_SMMLA_ZZ: "SMMLA.ZZ",
+ arm_SMMLA_R_EQ: "SMMLA.R.EQ",
+ arm_SMMLA_R_NE: "SMMLA.R.NE",
+ arm_SMMLA_R_CS: "SMMLA.R.CS",
+ arm_SMMLA_R_CC: "SMMLA.R.CC",
+ arm_SMMLA_R_MI: "SMMLA.R.MI",
+ arm_SMMLA_R_PL: "SMMLA.R.PL",
+ arm_SMMLA_R_VS: "SMMLA.R.VS",
+ arm_SMMLA_R_VC: "SMMLA.R.VC",
+ arm_SMMLA_R_HI: "SMMLA.R.HI",
+ arm_SMMLA_R_LS: "SMMLA.R.LS",
+ arm_SMMLA_R_GE: "SMMLA.R.GE",
+ arm_SMMLA_R_LT: "SMMLA.R.LT",
+ arm_SMMLA_R_GT: "SMMLA.R.GT",
+ arm_SMMLA_R_LE: "SMMLA.R.LE",
+ arm_SMMLA_R: "SMMLA.R",
+ arm_SMMLA_R_ZZ: "SMMLA.R.ZZ",
+ arm_SMMLS_EQ: "SMMLS.EQ",
+ arm_SMMLS_NE: "SMMLS.NE",
+ arm_SMMLS_CS: "SMMLS.CS",
+ arm_SMMLS_CC: "SMMLS.CC",
+ arm_SMMLS_MI: "SMMLS.MI",
+ arm_SMMLS_PL: "SMMLS.PL",
+ arm_SMMLS_VS: "SMMLS.VS",
+ arm_SMMLS_VC: "SMMLS.VC",
+ arm_SMMLS_HI: "SMMLS.HI",
+ arm_SMMLS_LS: "SMMLS.LS",
+ arm_SMMLS_GE: "SMMLS.GE",
+ arm_SMMLS_LT: "SMMLS.LT",
+ arm_SMMLS_GT: "SMMLS.GT",
+ arm_SMMLS_LE: "SMMLS.LE",
+ arm_SMMLS: "SMMLS",
+ arm_SMMLS_ZZ: "SMMLS.ZZ",
+ arm_SMMLS_R_EQ: "SMMLS.R.EQ",
+ arm_SMMLS_R_NE: "SMMLS.R.NE",
+ arm_SMMLS_R_CS: "SMMLS.R.CS",
+ arm_SMMLS_R_CC: "SMMLS.R.CC",
+ arm_SMMLS_R_MI: "SMMLS.R.MI",
+ arm_SMMLS_R_PL: "SMMLS.R.PL",
+ arm_SMMLS_R_VS: "SMMLS.R.VS",
+ arm_SMMLS_R_VC: "SMMLS.R.VC",
+ arm_SMMLS_R_HI: "SMMLS.R.HI",
+ arm_SMMLS_R_LS: "SMMLS.R.LS",
+ arm_SMMLS_R_GE: "SMMLS.R.GE",
+ arm_SMMLS_R_LT: "SMMLS.R.LT",
+ arm_SMMLS_R_GT: "SMMLS.R.GT",
+ arm_SMMLS_R_LE: "SMMLS.R.LE",
+ arm_SMMLS_R: "SMMLS.R",
+ arm_SMMLS_R_ZZ: "SMMLS.R.ZZ",
+ arm_SMMUL_EQ: "SMMUL.EQ",
+ arm_SMMUL_NE: "SMMUL.NE",
+ arm_SMMUL_CS: "SMMUL.CS",
+ arm_SMMUL_CC: "SMMUL.CC",
+ arm_SMMUL_MI: "SMMUL.MI",
+ arm_SMMUL_PL: "SMMUL.PL",
+ arm_SMMUL_VS: "SMMUL.VS",
+ arm_SMMUL_VC: "SMMUL.VC",
+ arm_SMMUL_HI: "SMMUL.HI",
+ arm_SMMUL_LS: "SMMUL.LS",
+ arm_SMMUL_GE: "SMMUL.GE",
+ arm_SMMUL_LT: "SMMUL.LT",
+ arm_SMMUL_GT: "SMMUL.GT",
+ arm_SMMUL_LE: "SMMUL.LE",
+ arm_SMMUL: "SMMUL",
+ arm_SMMUL_ZZ: "SMMUL.ZZ",
+ arm_SMMUL_R_EQ: "SMMUL.R.EQ",
+ arm_SMMUL_R_NE: "SMMUL.R.NE",
+ arm_SMMUL_R_CS: "SMMUL.R.CS",
+ arm_SMMUL_R_CC: "SMMUL.R.CC",
+ arm_SMMUL_R_MI: "SMMUL.R.MI",
+ arm_SMMUL_R_PL: "SMMUL.R.PL",
+ arm_SMMUL_R_VS: "SMMUL.R.VS",
+ arm_SMMUL_R_VC: "SMMUL.R.VC",
+ arm_SMMUL_R_HI: "SMMUL.R.HI",
+ arm_SMMUL_R_LS: "SMMUL.R.LS",
+ arm_SMMUL_R_GE: "SMMUL.R.GE",
+ arm_SMMUL_R_LT: "SMMUL.R.LT",
+ arm_SMMUL_R_GT: "SMMUL.R.GT",
+ arm_SMMUL_R_LE: "SMMUL.R.LE",
+ arm_SMMUL_R: "SMMUL.R",
+ arm_SMMUL_R_ZZ: "SMMUL.R.ZZ",
+ arm_SMUAD_EQ: "SMUAD.EQ",
+ arm_SMUAD_NE: "SMUAD.NE",
+ arm_SMUAD_CS: "SMUAD.CS",
+ arm_SMUAD_CC: "SMUAD.CC",
+ arm_SMUAD_MI: "SMUAD.MI",
+ arm_SMUAD_PL: "SMUAD.PL",
+ arm_SMUAD_VS: "SMUAD.VS",
+ arm_SMUAD_VC: "SMUAD.VC",
+ arm_SMUAD_HI: "SMUAD.HI",
+ arm_SMUAD_LS: "SMUAD.LS",
+ arm_SMUAD_GE: "SMUAD.GE",
+ arm_SMUAD_LT: "SMUAD.LT",
+ arm_SMUAD_GT: "SMUAD.GT",
+ arm_SMUAD_LE: "SMUAD.LE",
+ arm_SMUAD: "SMUAD",
+ arm_SMUAD_ZZ: "SMUAD.ZZ",
+ arm_SMUAD_X_EQ: "SMUAD.X.EQ",
+ arm_SMUAD_X_NE: "SMUAD.X.NE",
+ arm_SMUAD_X_CS: "SMUAD.X.CS",
+ arm_SMUAD_X_CC: "SMUAD.X.CC",
+ arm_SMUAD_X_MI: "SMUAD.X.MI",
+ arm_SMUAD_X_PL: "SMUAD.X.PL",
+ arm_SMUAD_X_VS: "SMUAD.X.VS",
+ arm_SMUAD_X_VC: "SMUAD.X.VC",
+ arm_SMUAD_X_HI: "SMUAD.X.HI",
+ arm_SMUAD_X_LS: "SMUAD.X.LS",
+ arm_SMUAD_X_GE: "SMUAD.X.GE",
+ arm_SMUAD_X_LT: "SMUAD.X.LT",
+ arm_SMUAD_X_GT: "SMUAD.X.GT",
+ arm_SMUAD_X_LE: "SMUAD.X.LE",
+ arm_SMUAD_X: "SMUAD.X",
+ arm_SMUAD_X_ZZ: "SMUAD.X.ZZ",
+ arm_SMULBB_EQ: "SMULBB.EQ",
+ arm_SMULBB_NE: "SMULBB.NE",
+ arm_SMULBB_CS: "SMULBB.CS",
+ arm_SMULBB_CC: "SMULBB.CC",
+ arm_SMULBB_MI: "SMULBB.MI",
+ arm_SMULBB_PL: "SMULBB.PL",
+ arm_SMULBB_VS: "SMULBB.VS",
+ arm_SMULBB_VC: "SMULBB.VC",
+ arm_SMULBB_HI: "SMULBB.HI",
+ arm_SMULBB_LS: "SMULBB.LS",
+ arm_SMULBB_GE: "SMULBB.GE",
+ arm_SMULBB_LT: "SMULBB.LT",
+ arm_SMULBB_GT: "SMULBB.GT",
+ arm_SMULBB_LE: "SMULBB.LE",
+ arm_SMULBB: "SMULBB",
+ arm_SMULBB_ZZ: "SMULBB.ZZ",
+ arm_SMULBT_EQ: "SMULBT.EQ",
+ arm_SMULBT_NE: "SMULBT.NE",
+ arm_SMULBT_CS: "SMULBT.CS",
+ arm_SMULBT_CC: "SMULBT.CC",
+ arm_SMULBT_MI: "SMULBT.MI",
+ arm_SMULBT_PL: "SMULBT.PL",
+ arm_SMULBT_VS: "SMULBT.VS",
+ arm_SMULBT_VC: "SMULBT.VC",
+ arm_SMULBT_HI: "SMULBT.HI",
+ arm_SMULBT_LS: "SMULBT.LS",
+ arm_SMULBT_GE: "SMULBT.GE",
+ arm_SMULBT_LT: "SMULBT.LT",
+ arm_SMULBT_GT: "SMULBT.GT",
+ arm_SMULBT_LE: "SMULBT.LE",
+ arm_SMULBT: "SMULBT",
+ arm_SMULBT_ZZ: "SMULBT.ZZ",
+ arm_SMULTB_EQ: "SMULTB.EQ",
+ arm_SMULTB_NE: "SMULTB.NE",
+ arm_SMULTB_CS: "SMULTB.CS",
+ arm_SMULTB_CC: "SMULTB.CC",
+ arm_SMULTB_MI: "SMULTB.MI",
+ arm_SMULTB_PL: "SMULTB.PL",
+ arm_SMULTB_VS: "SMULTB.VS",
+ arm_SMULTB_VC: "SMULTB.VC",
+ arm_SMULTB_HI: "SMULTB.HI",
+ arm_SMULTB_LS: "SMULTB.LS",
+ arm_SMULTB_GE: "SMULTB.GE",
+ arm_SMULTB_LT: "SMULTB.LT",
+ arm_SMULTB_GT: "SMULTB.GT",
+ arm_SMULTB_LE: "SMULTB.LE",
+ arm_SMULTB: "SMULTB",
+ arm_SMULTB_ZZ: "SMULTB.ZZ",
+ arm_SMULTT_EQ: "SMULTT.EQ",
+ arm_SMULTT_NE: "SMULTT.NE",
+ arm_SMULTT_CS: "SMULTT.CS",
+ arm_SMULTT_CC: "SMULTT.CC",
+ arm_SMULTT_MI: "SMULTT.MI",
+ arm_SMULTT_PL: "SMULTT.PL",
+ arm_SMULTT_VS: "SMULTT.VS",
+ arm_SMULTT_VC: "SMULTT.VC",
+ arm_SMULTT_HI: "SMULTT.HI",
+ arm_SMULTT_LS: "SMULTT.LS",
+ arm_SMULTT_GE: "SMULTT.GE",
+ arm_SMULTT_LT: "SMULTT.LT",
+ arm_SMULTT_GT: "SMULTT.GT",
+ arm_SMULTT_LE: "SMULTT.LE",
+ arm_SMULTT: "SMULTT",
+ arm_SMULTT_ZZ: "SMULTT.ZZ",
+ arm_SMULL_EQ: "SMULL.EQ",
+ arm_SMULL_NE: "SMULL.NE",
+ arm_SMULL_CS: "SMULL.CS",
+ arm_SMULL_CC: "SMULL.CC",
+ arm_SMULL_MI: "SMULL.MI",
+ arm_SMULL_PL: "SMULL.PL",
+ arm_SMULL_VS: "SMULL.VS",
+ arm_SMULL_VC: "SMULL.VC",
+ arm_SMULL_HI: "SMULL.HI",
+ arm_SMULL_LS: "SMULL.LS",
+ arm_SMULL_GE: "SMULL.GE",
+ arm_SMULL_LT: "SMULL.LT",
+ arm_SMULL_GT: "SMULL.GT",
+ arm_SMULL_LE: "SMULL.LE",
+ arm_SMULL: "SMULL",
+ arm_SMULL_ZZ: "SMULL.ZZ",
+ arm_SMULL_S_EQ: "SMULL.S.EQ",
+ arm_SMULL_S_NE: "SMULL.S.NE",
+ arm_SMULL_S_CS: "SMULL.S.CS",
+ arm_SMULL_S_CC: "SMULL.S.CC",
+ arm_SMULL_S_MI: "SMULL.S.MI",
+ arm_SMULL_S_PL: "SMULL.S.PL",
+ arm_SMULL_S_VS: "SMULL.S.VS",
+ arm_SMULL_S_VC: "SMULL.S.VC",
+ arm_SMULL_S_HI: "SMULL.S.HI",
+ arm_SMULL_S_LS: "SMULL.S.LS",
+ arm_SMULL_S_GE: "SMULL.S.GE",
+ arm_SMULL_S_LT: "SMULL.S.LT",
+ arm_SMULL_S_GT: "SMULL.S.GT",
+ arm_SMULL_S_LE: "SMULL.S.LE",
+ arm_SMULL_S: "SMULL.S",
+ arm_SMULL_S_ZZ: "SMULL.S.ZZ",
+ arm_SMULWB_EQ: "SMULWB.EQ",
+ arm_SMULWB_NE: "SMULWB.NE",
+ arm_SMULWB_CS: "SMULWB.CS",
+ arm_SMULWB_CC: "SMULWB.CC",
+ arm_SMULWB_MI: "SMULWB.MI",
+ arm_SMULWB_PL: "SMULWB.PL",
+ arm_SMULWB_VS: "SMULWB.VS",
+ arm_SMULWB_VC: "SMULWB.VC",
+ arm_SMULWB_HI: "SMULWB.HI",
+ arm_SMULWB_LS: "SMULWB.LS",
+ arm_SMULWB_GE: "SMULWB.GE",
+ arm_SMULWB_LT: "SMULWB.LT",
+ arm_SMULWB_GT: "SMULWB.GT",
+ arm_SMULWB_LE: "SMULWB.LE",
+ arm_SMULWB: "SMULWB",
+ arm_SMULWB_ZZ: "SMULWB.ZZ",
+ arm_SMULWT_EQ: "SMULWT.EQ",
+ arm_SMULWT_NE: "SMULWT.NE",
+ arm_SMULWT_CS: "SMULWT.CS",
+ arm_SMULWT_CC: "SMULWT.CC",
+ arm_SMULWT_MI: "SMULWT.MI",
+ arm_SMULWT_PL: "SMULWT.PL",
+ arm_SMULWT_VS: "SMULWT.VS",
+ arm_SMULWT_VC: "SMULWT.VC",
+ arm_SMULWT_HI: "SMULWT.HI",
+ arm_SMULWT_LS: "SMULWT.LS",
+ arm_SMULWT_GE: "SMULWT.GE",
+ arm_SMULWT_LT: "SMULWT.LT",
+ arm_SMULWT_GT: "SMULWT.GT",
+ arm_SMULWT_LE: "SMULWT.LE",
+ arm_SMULWT: "SMULWT",
+ arm_SMULWT_ZZ: "SMULWT.ZZ",
+ arm_SMUSD_EQ: "SMUSD.EQ",
+ arm_SMUSD_NE: "SMUSD.NE",
+ arm_SMUSD_CS: "SMUSD.CS",
+ arm_SMUSD_CC: "SMUSD.CC",
+ arm_SMUSD_MI: "SMUSD.MI",
+ arm_SMUSD_PL: "SMUSD.PL",
+ arm_SMUSD_VS: "SMUSD.VS",
+ arm_SMUSD_VC: "SMUSD.VC",
+ arm_SMUSD_HI: "SMUSD.HI",
+ arm_SMUSD_LS: "SMUSD.LS",
+ arm_SMUSD_GE: "SMUSD.GE",
+ arm_SMUSD_LT: "SMUSD.LT",
+ arm_SMUSD_GT: "SMUSD.GT",
+ arm_SMUSD_LE: "SMUSD.LE",
+ arm_SMUSD: "SMUSD",
+ arm_SMUSD_ZZ: "SMUSD.ZZ",
+ arm_SMUSD_X_EQ: "SMUSD.X.EQ",
+ arm_SMUSD_X_NE: "SMUSD.X.NE",
+ arm_SMUSD_X_CS: "SMUSD.X.CS",
+ arm_SMUSD_X_CC: "SMUSD.X.CC",
+ arm_SMUSD_X_MI: "SMUSD.X.MI",
+ arm_SMUSD_X_PL: "SMUSD.X.PL",
+ arm_SMUSD_X_VS: "SMUSD.X.VS",
+ arm_SMUSD_X_VC: "SMUSD.X.VC",
+ arm_SMUSD_X_HI: "SMUSD.X.HI",
+ arm_SMUSD_X_LS: "SMUSD.X.LS",
+ arm_SMUSD_X_GE: "SMUSD.X.GE",
+ arm_SMUSD_X_LT: "SMUSD.X.LT",
+ arm_SMUSD_X_GT: "SMUSD.X.GT",
+ arm_SMUSD_X_LE: "SMUSD.X.LE",
+ arm_SMUSD_X: "SMUSD.X",
+ arm_SMUSD_X_ZZ: "SMUSD.X.ZZ",
+ arm_SSAT_EQ: "SSAT.EQ",
+ arm_SSAT_NE: "SSAT.NE",
+ arm_SSAT_CS: "SSAT.CS",
+ arm_SSAT_CC: "SSAT.CC",
+ arm_SSAT_MI: "SSAT.MI",
+ arm_SSAT_PL: "SSAT.PL",
+ arm_SSAT_VS: "SSAT.VS",
+ arm_SSAT_VC: "SSAT.VC",
+ arm_SSAT_HI: "SSAT.HI",
+ arm_SSAT_LS: "SSAT.LS",
+ arm_SSAT_GE: "SSAT.GE",
+ arm_SSAT_LT: "SSAT.LT",
+ arm_SSAT_GT: "SSAT.GT",
+ arm_SSAT_LE: "SSAT.LE",
+ arm_SSAT: "SSAT",
+ arm_SSAT_ZZ: "SSAT.ZZ",
+ arm_SSAT16_EQ: "SSAT16.EQ",
+ arm_SSAT16_NE: "SSAT16.NE",
+ arm_SSAT16_CS: "SSAT16.CS",
+ arm_SSAT16_CC: "SSAT16.CC",
+ arm_SSAT16_MI: "SSAT16.MI",
+ arm_SSAT16_PL: "SSAT16.PL",
+ arm_SSAT16_VS: "SSAT16.VS",
+ arm_SSAT16_VC: "SSAT16.VC",
+ arm_SSAT16_HI: "SSAT16.HI",
+ arm_SSAT16_LS: "SSAT16.LS",
+ arm_SSAT16_GE: "SSAT16.GE",
+ arm_SSAT16_LT: "SSAT16.LT",
+ arm_SSAT16_GT: "SSAT16.GT",
+ arm_SSAT16_LE: "SSAT16.LE",
+ arm_SSAT16: "SSAT16",
+ arm_SSAT16_ZZ: "SSAT16.ZZ",
+ arm_SSAX_EQ: "SSAX.EQ",
+ arm_SSAX_NE: "SSAX.NE",
+ arm_SSAX_CS: "SSAX.CS",
+ arm_SSAX_CC: "SSAX.CC",
+ arm_SSAX_MI: "SSAX.MI",
+ arm_SSAX_PL: "SSAX.PL",
+ arm_SSAX_VS: "SSAX.VS",
+ arm_SSAX_VC: "SSAX.VC",
+ arm_SSAX_HI: "SSAX.HI",
+ arm_SSAX_LS: "SSAX.LS",
+ arm_SSAX_GE: "SSAX.GE",
+ arm_SSAX_LT: "SSAX.LT",
+ arm_SSAX_GT: "SSAX.GT",
+ arm_SSAX_LE: "SSAX.LE",
+ arm_SSAX: "SSAX",
+ arm_SSAX_ZZ: "SSAX.ZZ",
+ arm_SSUB16_EQ: "SSUB16.EQ",
+ arm_SSUB16_NE: "SSUB16.NE",
+ arm_SSUB16_CS: "SSUB16.CS",
+ arm_SSUB16_CC: "SSUB16.CC",
+ arm_SSUB16_MI: "SSUB16.MI",
+ arm_SSUB16_PL: "SSUB16.PL",
+ arm_SSUB16_VS: "SSUB16.VS",
+ arm_SSUB16_VC: "SSUB16.VC",
+ arm_SSUB16_HI: "SSUB16.HI",
+ arm_SSUB16_LS: "SSUB16.LS",
+ arm_SSUB16_GE: "SSUB16.GE",
+ arm_SSUB16_LT: "SSUB16.LT",
+ arm_SSUB16_GT: "SSUB16.GT",
+ arm_SSUB16_LE: "SSUB16.LE",
+ arm_SSUB16: "SSUB16",
+ arm_SSUB16_ZZ: "SSUB16.ZZ",
+ arm_SSUB8_EQ: "SSUB8.EQ",
+ arm_SSUB8_NE: "SSUB8.NE",
+ arm_SSUB8_CS: "SSUB8.CS",
+ arm_SSUB8_CC: "SSUB8.CC",
+ arm_SSUB8_MI: "SSUB8.MI",
+ arm_SSUB8_PL: "SSUB8.PL",
+ arm_SSUB8_VS: "SSUB8.VS",
+ arm_SSUB8_VC: "SSUB8.VC",
+ arm_SSUB8_HI: "SSUB8.HI",
+ arm_SSUB8_LS: "SSUB8.LS",
+ arm_SSUB8_GE: "SSUB8.GE",
+ arm_SSUB8_LT: "SSUB8.LT",
+ arm_SSUB8_GT: "SSUB8.GT",
+ arm_SSUB8_LE: "SSUB8.LE",
+ arm_SSUB8: "SSUB8",
+ arm_SSUB8_ZZ: "SSUB8.ZZ",
+ arm_STM_EQ: "STM.EQ",
+ arm_STM_NE: "STM.NE",
+ arm_STM_CS: "STM.CS",
+ arm_STM_CC: "STM.CC",
+ arm_STM_MI: "STM.MI",
+ arm_STM_PL: "STM.PL",
+ arm_STM_VS: "STM.VS",
+ arm_STM_VC: "STM.VC",
+ arm_STM_HI: "STM.HI",
+ arm_STM_LS: "STM.LS",
+ arm_STM_GE: "STM.GE",
+ arm_STM_LT: "STM.LT",
+ arm_STM_GT: "STM.GT",
+ arm_STM_LE: "STM.LE",
+ arm_STM: "STM",
+ arm_STM_ZZ: "STM.ZZ",
+ arm_STMDA_EQ: "STMDA.EQ",
+ arm_STMDA_NE: "STMDA.NE",
+ arm_STMDA_CS: "STMDA.CS",
+ arm_STMDA_CC: "STMDA.CC",
+ arm_STMDA_MI: "STMDA.MI",
+ arm_STMDA_PL: "STMDA.PL",
+ arm_STMDA_VS: "STMDA.VS",
+ arm_STMDA_VC: "STMDA.VC",
+ arm_STMDA_HI: "STMDA.HI",
+ arm_STMDA_LS: "STMDA.LS",
+ arm_STMDA_GE: "STMDA.GE",
+ arm_STMDA_LT: "STMDA.LT",
+ arm_STMDA_GT: "STMDA.GT",
+ arm_STMDA_LE: "STMDA.LE",
+ arm_STMDA: "STMDA",
+ arm_STMDA_ZZ: "STMDA.ZZ",
+ arm_STMDB_EQ: "STMDB.EQ",
+ arm_STMDB_NE: "STMDB.NE",
+ arm_STMDB_CS: "STMDB.CS",
+ arm_STMDB_CC: "STMDB.CC",
+ arm_STMDB_MI: "STMDB.MI",
+ arm_STMDB_PL: "STMDB.PL",
+ arm_STMDB_VS: "STMDB.VS",
+ arm_STMDB_VC: "STMDB.VC",
+ arm_STMDB_HI: "STMDB.HI",
+ arm_STMDB_LS: "STMDB.LS",
+ arm_STMDB_GE: "STMDB.GE",
+ arm_STMDB_LT: "STMDB.LT",
+ arm_STMDB_GT: "STMDB.GT",
+ arm_STMDB_LE: "STMDB.LE",
+ arm_STMDB: "STMDB",
+ arm_STMDB_ZZ: "STMDB.ZZ",
+ arm_STMIB_EQ: "STMIB.EQ",
+ arm_STMIB_NE: "STMIB.NE",
+ arm_STMIB_CS: "STMIB.CS",
+ arm_STMIB_CC: "STMIB.CC",
+ arm_STMIB_MI: "STMIB.MI",
+ arm_STMIB_PL: "STMIB.PL",
+ arm_STMIB_VS: "STMIB.VS",
+ arm_STMIB_VC: "STMIB.VC",
+ arm_STMIB_HI: "STMIB.HI",
+ arm_STMIB_LS: "STMIB.LS",
+ arm_STMIB_GE: "STMIB.GE",
+ arm_STMIB_LT: "STMIB.LT",
+ arm_STMIB_GT: "STMIB.GT",
+ arm_STMIB_LE: "STMIB.LE",
+ arm_STMIB: "STMIB",
+ arm_STMIB_ZZ: "STMIB.ZZ",
+ arm_STR_EQ: "STR.EQ",
+ arm_STR_NE: "STR.NE",
+ arm_STR_CS: "STR.CS",
+ arm_STR_CC: "STR.CC",
+ arm_STR_MI: "STR.MI",
+ arm_STR_PL: "STR.PL",
+ arm_STR_VS: "STR.VS",
+ arm_STR_VC: "STR.VC",
+ arm_STR_HI: "STR.HI",
+ arm_STR_LS: "STR.LS",
+ arm_STR_GE: "STR.GE",
+ arm_STR_LT: "STR.LT",
+ arm_STR_GT: "STR.GT",
+ arm_STR_LE: "STR.LE",
+ arm_STR: "STR",
+ arm_STR_ZZ: "STR.ZZ",
+ arm_STRB_EQ: "STRB.EQ",
+ arm_STRB_NE: "STRB.NE",
+ arm_STRB_CS: "STRB.CS",
+ arm_STRB_CC: "STRB.CC",
+ arm_STRB_MI: "STRB.MI",
+ arm_STRB_PL: "STRB.PL",
+ arm_STRB_VS: "STRB.VS",
+ arm_STRB_VC: "STRB.VC",
+ arm_STRB_HI: "STRB.HI",
+ arm_STRB_LS: "STRB.LS",
+ arm_STRB_GE: "STRB.GE",
+ arm_STRB_LT: "STRB.LT",
+ arm_STRB_GT: "STRB.GT",
+ arm_STRB_LE: "STRB.LE",
+ arm_STRB: "STRB",
+ arm_STRB_ZZ: "STRB.ZZ",
+ arm_STRBT_EQ: "STRBT.EQ",
+ arm_STRBT_NE: "STRBT.NE",
+ arm_STRBT_CS: "STRBT.CS",
+ arm_STRBT_CC: "STRBT.CC",
+ arm_STRBT_MI: "STRBT.MI",
+ arm_STRBT_PL: "STRBT.PL",
+ arm_STRBT_VS: "STRBT.VS",
+ arm_STRBT_VC: "STRBT.VC",
+ arm_STRBT_HI: "STRBT.HI",
+ arm_STRBT_LS: "STRBT.LS",
+ arm_STRBT_GE: "STRBT.GE",
+ arm_STRBT_LT: "STRBT.LT",
+ arm_STRBT_GT: "STRBT.GT",
+ arm_STRBT_LE: "STRBT.LE",
+ arm_STRBT: "STRBT",
+ arm_STRBT_ZZ: "STRBT.ZZ",
+ arm_STRD_EQ: "STRD.EQ",
+ arm_STRD_NE: "STRD.NE",
+ arm_STRD_CS: "STRD.CS",
+ arm_STRD_CC: "STRD.CC",
+ arm_STRD_MI: "STRD.MI",
+ arm_STRD_PL: "STRD.PL",
+ arm_STRD_VS: "STRD.VS",
+ arm_STRD_VC: "STRD.VC",
+ arm_STRD_HI: "STRD.HI",
+ arm_STRD_LS: "STRD.LS",
+ arm_STRD_GE: "STRD.GE",
+ arm_STRD_LT: "STRD.LT",
+ arm_STRD_GT: "STRD.GT",
+ arm_STRD_LE: "STRD.LE",
+ arm_STRD: "STRD",
+ arm_STRD_ZZ: "STRD.ZZ",
+ arm_STREX_EQ: "STREX.EQ",
+ arm_STREX_NE: "STREX.NE",
+ arm_STREX_CS: "STREX.CS",
+ arm_STREX_CC: "STREX.CC",
+ arm_STREX_MI: "STREX.MI",
+ arm_STREX_PL: "STREX.PL",
+ arm_STREX_VS: "STREX.VS",
+ arm_STREX_VC: "STREX.VC",
+ arm_STREX_HI: "STREX.HI",
+ arm_STREX_LS: "STREX.LS",
+ arm_STREX_GE: "STREX.GE",
+ arm_STREX_LT: "STREX.LT",
+ arm_STREX_GT: "STREX.GT",
+ arm_STREX_LE: "STREX.LE",
+ arm_STREX: "STREX",
+ arm_STREX_ZZ: "STREX.ZZ",
+ arm_STREXB_EQ: "STREXB.EQ",
+ arm_STREXB_NE: "STREXB.NE",
+ arm_STREXB_CS: "STREXB.CS",
+ arm_STREXB_CC: "STREXB.CC",
+ arm_STREXB_MI: "STREXB.MI",
+ arm_STREXB_PL: "STREXB.PL",
+ arm_STREXB_VS: "STREXB.VS",
+ arm_STREXB_VC: "STREXB.VC",
+ arm_STREXB_HI: "STREXB.HI",
+ arm_STREXB_LS: "STREXB.LS",
+ arm_STREXB_GE: "STREXB.GE",
+ arm_STREXB_LT: "STREXB.LT",
+ arm_STREXB_GT: "STREXB.GT",
+ arm_STREXB_LE: "STREXB.LE",
+ arm_STREXB: "STREXB",
+ arm_STREXB_ZZ: "STREXB.ZZ",
+ arm_STREXD_EQ: "STREXD.EQ",
+ arm_STREXD_NE: "STREXD.NE",
+ arm_STREXD_CS: "STREXD.CS",
+ arm_STREXD_CC: "STREXD.CC",
+ arm_STREXD_MI: "STREXD.MI",
+ arm_STREXD_PL: "STREXD.PL",
+ arm_STREXD_VS: "STREXD.VS",
+ arm_STREXD_VC: "STREXD.VC",
+ arm_STREXD_HI: "STREXD.HI",
+ arm_STREXD_LS: "STREXD.LS",
+ arm_STREXD_GE: "STREXD.GE",
+ arm_STREXD_LT: "STREXD.LT",
+ arm_STREXD_GT: "STREXD.GT",
+ arm_STREXD_LE: "STREXD.LE",
+ arm_STREXD: "STREXD",
+ arm_STREXD_ZZ: "STREXD.ZZ",
+ arm_STREXH_EQ: "STREXH.EQ",
+ arm_STREXH_NE: "STREXH.NE",
+ arm_STREXH_CS: "STREXH.CS",
+ arm_STREXH_CC: "STREXH.CC",
+ arm_STREXH_MI: "STREXH.MI",
+ arm_STREXH_PL: "STREXH.PL",
+ arm_STREXH_VS: "STREXH.VS",
+ arm_STREXH_VC: "STREXH.VC",
+ arm_STREXH_HI: "STREXH.HI",
+ arm_STREXH_LS: "STREXH.LS",
+ arm_STREXH_GE: "STREXH.GE",
+ arm_STREXH_LT: "STREXH.LT",
+ arm_STREXH_GT: "STREXH.GT",
+ arm_STREXH_LE: "STREXH.LE",
+ arm_STREXH: "STREXH",
+ arm_STREXH_ZZ: "STREXH.ZZ",
+ arm_STRH_EQ: "STRH.EQ",
+ arm_STRH_NE: "STRH.NE",
+ arm_STRH_CS: "STRH.CS",
+ arm_STRH_CC: "STRH.CC",
+ arm_STRH_MI: "STRH.MI",
+ arm_STRH_PL: "STRH.PL",
+ arm_STRH_VS: "STRH.VS",
+ arm_STRH_VC: "STRH.VC",
+ arm_STRH_HI: "STRH.HI",
+ arm_STRH_LS: "STRH.LS",
+ arm_STRH_GE: "STRH.GE",
+ arm_STRH_LT: "STRH.LT",
+ arm_STRH_GT: "STRH.GT",
+ arm_STRH_LE: "STRH.LE",
+ arm_STRH: "STRH",
+ arm_STRH_ZZ: "STRH.ZZ",
+ arm_STRHT_EQ: "STRHT.EQ",
+ arm_STRHT_NE: "STRHT.NE",
+ arm_STRHT_CS: "STRHT.CS",
+ arm_STRHT_CC: "STRHT.CC",
+ arm_STRHT_MI: "STRHT.MI",
+ arm_STRHT_PL: "STRHT.PL",
+ arm_STRHT_VS: "STRHT.VS",
+ arm_STRHT_VC: "STRHT.VC",
+ arm_STRHT_HI: "STRHT.HI",
+ arm_STRHT_LS: "STRHT.LS",
+ arm_STRHT_GE: "STRHT.GE",
+ arm_STRHT_LT: "STRHT.LT",
+ arm_STRHT_GT: "STRHT.GT",
+ arm_STRHT_LE: "STRHT.LE",
+ arm_STRHT: "STRHT",
+ arm_STRHT_ZZ: "STRHT.ZZ",
+ arm_STRT_EQ: "STRT.EQ",
+ arm_STRT_NE: "STRT.NE",
+ arm_STRT_CS: "STRT.CS",
+ arm_STRT_CC: "STRT.CC",
+ arm_STRT_MI: "STRT.MI",
+ arm_STRT_PL: "STRT.PL",
+ arm_STRT_VS: "STRT.VS",
+ arm_STRT_VC: "STRT.VC",
+ arm_STRT_HI: "STRT.HI",
+ arm_STRT_LS: "STRT.LS",
+ arm_STRT_GE: "STRT.GE",
+ arm_STRT_LT: "STRT.LT",
+ arm_STRT_GT: "STRT.GT",
+ arm_STRT_LE: "STRT.LE",
+ arm_STRT: "STRT",
+ arm_STRT_ZZ: "STRT.ZZ",
+ arm_SUB_EQ: "SUB.EQ",
+ arm_SUB_NE: "SUB.NE",
+ arm_SUB_CS: "SUB.CS",
+ arm_SUB_CC: "SUB.CC",
+ arm_SUB_MI: "SUB.MI",
+ arm_SUB_PL: "SUB.PL",
+ arm_SUB_VS: "SUB.VS",
+ arm_SUB_VC: "SUB.VC",
+ arm_SUB_HI: "SUB.HI",
+ arm_SUB_LS: "SUB.LS",
+ arm_SUB_GE: "SUB.GE",
+ arm_SUB_LT: "SUB.LT",
+ arm_SUB_GT: "SUB.GT",
+ arm_SUB_LE: "SUB.LE",
+ arm_SUB: "SUB",
+ arm_SUB_ZZ: "SUB.ZZ",
+ arm_SUB_S_EQ: "SUB.S.EQ",
+ arm_SUB_S_NE: "SUB.S.NE",
+ arm_SUB_S_CS: "SUB.S.CS",
+ arm_SUB_S_CC: "SUB.S.CC",
+ arm_SUB_S_MI: "SUB.S.MI",
+ arm_SUB_S_PL: "SUB.S.PL",
+ arm_SUB_S_VS: "SUB.S.VS",
+ arm_SUB_S_VC: "SUB.S.VC",
+ arm_SUB_S_HI: "SUB.S.HI",
+ arm_SUB_S_LS: "SUB.S.LS",
+ arm_SUB_S_GE: "SUB.S.GE",
+ arm_SUB_S_LT: "SUB.S.LT",
+ arm_SUB_S_GT: "SUB.S.GT",
+ arm_SUB_S_LE: "SUB.S.LE",
+ arm_SUB_S: "SUB.S",
+ arm_SUB_S_ZZ: "SUB.S.ZZ",
+ arm_SVC_EQ: "SVC.EQ",
+ arm_SVC_NE: "SVC.NE",
+ arm_SVC_CS: "SVC.CS",
+ arm_SVC_CC: "SVC.CC",
+ arm_SVC_MI: "SVC.MI",
+ arm_SVC_PL: "SVC.PL",
+ arm_SVC_VS: "SVC.VS",
+ arm_SVC_VC: "SVC.VC",
+ arm_SVC_HI: "SVC.HI",
+ arm_SVC_LS: "SVC.LS",
+ arm_SVC_GE: "SVC.GE",
+ arm_SVC_LT: "SVC.LT",
+ arm_SVC_GT: "SVC.GT",
+ arm_SVC_LE: "SVC.LE",
+ arm_SVC: "SVC",
+ arm_SVC_ZZ: "SVC.ZZ",
+ arm_SWP_EQ: "SWP.EQ",
+ arm_SWP_NE: "SWP.NE",
+ arm_SWP_CS: "SWP.CS",
+ arm_SWP_CC: "SWP.CC",
+ arm_SWP_MI: "SWP.MI",
+ arm_SWP_PL: "SWP.PL",
+ arm_SWP_VS: "SWP.VS",
+ arm_SWP_VC: "SWP.VC",
+ arm_SWP_HI: "SWP.HI",
+ arm_SWP_LS: "SWP.LS",
+ arm_SWP_GE: "SWP.GE",
+ arm_SWP_LT: "SWP.LT",
+ arm_SWP_GT: "SWP.GT",
+ arm_SWP_LE: "SWP.LE",
+ arm_SWP: "SWP",
+ arm_SWP_ZZ: "SWP.ZZ",
+ arm_SWP_B_EQ: "SWP.B.EQ",
+ arm_SWP_B_NE: "SWP.B.NE",
+ arm_SWP_B_CS: "SWP.B.CS",
+ arm_SWP_B_CC: "SWP.B.CC",
+ arm_SWP_B_MI: "SWP.B.MI",
+ arm_SWP_B_PL: "SWP.B.PL",
+ arm_SWP_B_VS: "SWP.B.VS",
+ arm_SWP_B_VC: "SWP.B.VC",
+ arm_SWP_B_HI: "SWP.B.HI",
+ arm_SWP_B_LS: "SWP.B.LS",
+ arm_SWP_B_GE: "SWP.B.GE",
+ arm_SWP_B_LT: "SWP.B.LT",
+ arm_SWP_B_GT: "SWP.B.GT",
+ arm_SWP_B_LE: "SWP.B.LE",
+ arm_SWP_B: "SWP.B",
+ arm_SWP_B_ZZ: "SWP.B.ZZ",
+ arm_SXTAB_EQ: "SXTAB.EQ",
+ arm_SXTAB_NE: "SXTAB.NE",
+ arm_SXTAB_CS: "SXTAB.CS",
+ arm_SXTAB_CC: "SXTAB.CC",
+ arm_SXTAB_MI: "SXTAB.MI",
+ arm_SXTAB_PL: "SXTAB.PL",
+ arm_SXTAB_VS: "SXTAB.VS",
+ arm_SXTAB_VC: "SXTAB.VC",
+ arm_SXTAB_HI: "SXTAB.HI",
+ arm_SXTAB_LS: "SXTAB.LS",
+ arm_SXTAB_GE: "SXTAB.GE",
+ arm_SXTAB_LT: "SXTAB.LT",
+ arm_SXTAB_GT: "SXTAB.GT",
+ arm_SXTAB_LE: "SXTAB.LE",
+ arm_SXTAB: "SXTAB",
+ arm_SXTAB_ZZ: "SXTAB.ZZ",
+ arm_SXTAB16_EQ: "SXTAB16.EQ",
+ arm_SXTAB16_NE: "SXTAB16.NE",
+ arm_SXTAB16_CS: "SXTAB16.CS",
+ arm_SXTAB16_CC: "SXTAB16.CC",
+ arm_SXTAB16_MI: "SXTAB16.MI",
+ arm_SXTAB16_PL: "SXTAB16.PL",
+ arm_SXTAB16_VS: "SXTAB16.VS",
+ arm_SXTAB16_VC: "SXTAB16.VC",
+ arm_SXTAB16_HI: "SXTAB16.HI",
+ arm_SXTAB16_LS: "SXTAB16.LS",
+ arm_SXTAB16_GE: "SXTAB16.GE",
+ arm_SXTAB16_LT: "SXTAB16.LT",
+ arm_SXTAB16_GT: "SXTAB16.GT",
+ arm_SXTAB16_LE: "SXTAB16.LE",
+ arm_SXTAB16: "SXTAB16",
+ arm_SXTAB16_ZZ: "SXTAB16.ZZ",
+ arm_SXTAH_EQ: "SXTAH.EQ",
+ arm_SXTAH_NE: "SXTAH.NE",
+ arm_SXTAH_CS: "SXTAH.CS",
+ arm_SXTAH_CC: "SXTAH.CC",
+ arm_SXTAH_MI: "SXTAH.MI",
+ arm_SXTAH_PL: "SXTAH.PL",
+ arm_SXTAH_VS: "SXTAH.VS",
+ arm_SXTAH_VC: "SXTAH.VC",
+ arm_SXTAH_HI: "SXTAH.HI",
+ arm_SXTAH_LS: "SXTAH.LS",
+ arm_SXTAH_GE: "SXTAH.GE",
+ arm_SXTAH_LT: "SXTAH.LT",
+ arm_SXTAH_GT: "SXTAH.GT",
+ arm_SXTAH_LE: "SXTAH.LE",
+ arm_SXTAH: "SXTAH",
+ arm_SXTAH_ZZ: "SXTAH.ZZ",
+ arm_SXTB_EQ: "SXTB.EQ",
+ arm_SXTB_NE: "SXTB.NE",
+ arm_SXTB_CS: "SXTB.CS",
+ arm_SXTB_CC: "SXTB.CC",
+ arm_SXTB_MI: "SXTB.MI",
+ arm_SXTB_PL: "SXTB.PL",
+ arm_SXTB_VS: "SXTB.VS",
+ arm_SXTB_VC: "SXTB.VC",
+ arm_SXTB_HI: "SXTB.HI",
+ arm_SXTB_LS: "SXTB.LS",
+ arm_SXTB_GE: "SXTB.GE",
+ arm_SXTB_LT: "SXTB.LT",
+ arm_SXTB_GT: "SXTB.GT",
+ arm_SXTB_LE: "SXTB.LE",
+ arm_SXTB: "SXTB",
+ arm_SXTB_ZZ: "SXTB.ZZ",
+ arm_SXTB16_EQ: "SXTB16.EQ",
+ arm_SXTB16_NE: "SXTB16.NE",
+ arm_SXTB16_CS: "SXTB16.CS",
+ arm_SXTB16_CC: "SXTB16.CC",
+ arm_SXTB16_MI: "SXTB16.MI",
+ arm_SXTB16_PL: "SXTB16.PL",
+ arm_SXTB16_VS: "SXTB16.VS",
+ arm_SXTB16_VC: "SXTB16.VC",
+ arm_SXTB16_HI: "SXTB16.HI",
+ arm_SXTB16_LS: "SXTB16.LS",
+ arm_SXTB16_GE: "SXTB16.GE",
+ arm_SXTB16_LT: "SXTB16.LT",
+ arm_SXTB16_GT: "SXTB16.GT",
+ arm_SXTB16_LE: "SXTB16.LE",
+ arm_SXTB16: "SXTB16",
+ arm_SXTB16_ZZ: "SXTB16.ZZ",
+ arm_SXTH_EQ: "SXTH.EQ",
+ arm_SXTH_NE: "SXTH.NE",
+ arm_SXTH_CS: "SXTH.CS",
+ arm_SXTH_CC: "SXTH.CC",
+ arm_SXTH_MI: "SXTH.MI",
+ arm_SXTH_PL: "SXTH.PL",
+ arm_SXTH_VS: "SXTH.VS",
+ arm_SXTH_VC: "SXTH.VC",
+ arm_SXTH_HI: "SXTH.HI",
+ arm_SXTH_LS: "SXTH.LS",
+ arm_SXTH_GE: "SXTH.GE",
+ arm_SXTH_LT: "SXTH.LT",
+ arm_SXTH_GT: "SXTH.GT",
+ arm_SXTH_LE: "SXTH.LE",
+ arm_SXTH: "SXTH",
+ arm_SXTH_ZZ: "SXTH.ZZ",
+ arm_TEQ_EQ: "TEQ.EQ",
+ arm_TEQ_NE: "TEQ.NE",
+ arm_TEQ_CS: "TEQ.CS",
+ arm_TEQ_CC: "TEQ.CC",
+ arm_TEQ_MI: "TEQ.MI",
+ arm_TEQ_PL: "TEQ.PL",
+ arm_TEQ_VS: "TEQ.VS",
+ arm_TEQ_VC: "TEQ.VC",
+ arm_TEQ_HI: "TEQ.HI",
+ arm_TEQ_LS: "TEQ.LS",
+ arm_TEQ_GE: "TEQ.GE",
+ arm_TEQ_LT: "TEQ.LT",
+ arm_TEQ_GT: "TEQ.GT",
+ arm_TEQ_LE: "TEQ.LE",
+ arm_TEQ: "TEQ",
+ arm_TEQ_ZZ: "TEQ.ZZ",
+ arm_TST_EQ: "TST.EQ",
+ arm_TST_NE: "TST.NE",
+ arm_TST_CS: "TST.CS",
+ arm_TST_CC: "TST.CC",
+ arm_TST_MI: "TST.MI",
+ arm_TST_PL: "TST.PL",
+ arm_TST_VS: "TST.VS",
+ arm_TST_VC: "TST.VC",
+ arm_TST_HI: "TST.HI",
+ arm_TST_LS: "TST.LS",
+ arm_TST_GE: "TST.GE",
+ arm_TST_LT: "TST.LT",
+ arm_TST_GT: "TST.GT",
+ arm_TST_LE: "TST.LE",
+ arm_TST: "TST",
+ arm_TST_ZZ: "TST.ZZ",
+ arm_UADD16_EQ: "UADD16.EQ",
+ arm_UADD16_NE: "UADD16.NE",
+ arm_UADD16_CS: "UADD16.CS",
+ arm_UADD16_CC: "UADD16.CC",
+ arm_UADD16_MI: "UADD16.MI",
+ arm_UADD16_PL: "UADD16.PL",
+ arm_UADD16_VS: "UADD16.VS",
+ arm_UADD16_VC: "UADD16.VC",
+ arm_UADD16_HI: "UADD16.HI",
+ arm_UADD16_LS: "UADD16.LS",
+ arm_UADD16_GE: "UADD16.GE",
+ arm_UADD16_LT: "UADD16.LT",
+ arm_UADD16_GT: "UADD16.GT",
+ arm_UADD16_LE: "UADD16.LE",
+ arm_UADD16: "UADD16",
+ arm_UADD16_ZZ: "UADD16.ZZ",
+ arm_UADD8_EQ: "UADD8.EQ",
+ arm_UADD8_NE: "UADD8.NE",
+ arm_UADD8_CS: "UADD8.CS",
+ arm_UADD8_CC: "UADD8.CC",
+ arm_UADD8_MI: "UADD8.MI",
+ arm_UADD8_PL: "UADD8.PL",
+ arm_UADD8_VS: "UADD8.VS",
+ arm_UADD8_VC: "UADD8.VC",
+ arm_UADD8_HI: "UADD8.HI",
+ arm_UADD8_LS: "UADD8.LS",
+ arm_UADD8_GE: "UADD8.GE",
+ arm_UADD8_LT: "UADD8.LT",
+ arm_UADD8_GT: "UADD8.GT",
+ arm_UADD8_LE: "UADD8.LE",
+ arm_UADD8: "UADD8",
+ arm_UADD8_ZZ: "UADD8.ZZ",
+ arm_UASX_EQ: "UASX.EQ",
+ arm_UASX_NE: "UASX.NE",
+ arm_UASX_CS: "UASX.CS",
+ arm_UASX_CC: "UASX.CC",
+ arm_UASX_MI: "UASX.MI",
+ arm_UASX_PL: "UASX.PL",
+ arm_UASX_VS: "UASX.VS",
+ arm_UASX_VC: "UASX.VC",
+ arm_UASX_HI: "UASX.HI",
+ arm_UASX_LS: "UASX.LS",
+ arm_UASX_GE: "UASX.GE",
+ arm_UASX_LT: "UASX.LT",
+ arm_UASX_GT: "UASX.GT",
+ arm_UASX_LE: "UASX.LE",
+ arm_UASX: "UASX",
+ arm_UASX_ZZ: "UASX.ZZ",
+ arm_UBFX_EQ: "UBFX.EQ",
+ arm_UBFX_NE: "UBFX.NE",
+ arm_UBFX_CS: "UBFX.CS",
+ arm_UBFX_CC: "UBFX.CC",
+ arm_UBFX_MI: "UBFX.MI",
+ arm_UBFX_PL: "UBFX.PL",
+ arm_UBFX_VS: "UBFX.VS",
+ arm_UBFX_VC: "UBFX.VC",
+ arm_UBFX_HI: "UBFX.HI",
+ arm_UBFX_LS: "UBFX.LS",
+ arm_UBFX_GE: "UBFX.GE",
+ arm_UBFX_LT: "UBFX.LT",
+ arm_UBFX_GT: "UBFX.GT",
+ arm_UBFX_LE: "UBFX.LE",
+ arm_UBFX: "UBFX",
+ arm_UBFX_ZZ: "UBFX.ZZ",
+ arm_UHADD16_EQ: "UHADD16.EQ",
+ arm_UHADD16_NE: "UHADD16.NE",
+ arm_UHADD16_CS: "UHADD16.CS",
+ arm_UHADD16_CC: "UHADD16.CC",
+ arm_UHADD16_MI: "UHADD16.MI",
+ arm_UHADD16_PL: "UHADD16.PL",
+ arm_UHADD16_VS: "UHADD16.VS",
+ arm_UHADD16_VC: "UHADD16.VC",
+ arm_UHADD16_HI: "UHADD16.HI",
+ arm_UHADD16_LS: "UHADD16.LS",
+ arm_UHADD16_GE: "UHADD16.GE",
+ arm_UHADD16_LT: "UHADD16.LT",
+ arm_UHADD16_GT: "UHADD16.GT",
+ arm_UHADD16_LE: "UHADD16.LE",
+ arm_UHADD16: "UHADD16",
+ arm_UHADD16_ZZ: "UHADD16.ZZ",
+ arm_UHADD8_EQ: "UHADD8.EQ",
+ arm_UHADD8_NE: "UHADD8.NE",
+ arm_UHADD8_CS: "UHADD8.CS",
+ arm_UHADD8_CC: "UHADD8.CC",
+ arm_UHADD8_MI: "UHADD8.MI",
+ arm_UHADD8_PL: "UHADD8.PL",
+ arm_UHADD8_VS: "UHADD8.VS",
+ arm_UHADD8_VC: "UHADD8.VC",
+ arm_UHADD8_HI: "UHADD8.HI",
+ arm_UHADD8_LS: "UHADD8.LS",
+ arm_UHADD8_GE: "UHADD8.GE",
+ arm_UHADD8_LT: "UHADD8.LT",
+ arm_UHADD8_GT: "UHADD8.GT",
+ arm_UHADD8_LE: "UHADD8.LE",
+ arm_UHADD8: "UHADD8",
+ arm_UHADD8_ZZ: "UHADD8.ZZ",
+ arm_UHASX_EQ: "UHASX.EQ",
+ arm_UHASX_NE: "UHASX.NE",
+ arm_UHASX_CS: "UHASX.CS",
+ arm_UHASX_CC: "UHASX.CC",
+ arm_UHASX_MI: "UHASX.MI",
+ arm_UHASX_PL: "UHASX.PL",
+ arm_UHASX_VS: "UHASX.VS",
+ arm_UHASX_VC: "UHASX.VC",
+ arm_UHASX_HI: "UHASX.HI",
+ arm_UHASX_LS: "UHASX.LS",
+ arm_UHASX_GE: "UHASX.GE",
+ arm_UHASX_LT: "UHASX.LT",
+ arm_UHASX_GT: "UHASX.GT",
+ arm_UHASX_LE: "UHASX.LE",
+ arm_UHASX: "UHASX",
+ arm_UHASX_ZZ: "UHASX.ZZ",
+ arm_UHSAX_EQ: "UHSAX.EQ",
+ arm_UHSAX_NE: "UHSAX.NE",
+ arm_UHSAX_CS: "UHSAX.CS",
+ arm_UHSAX_CC: "UHSAX.CC",
+ arm_UHSAX_MI: "UHSAX.MI",
+ arm_UHSAX_PL: "UHSAX.PL",
+ arm_UHSAX_VS: "UHSAX.VS",
+ arm_UHSAX_VC: "UHSAX.VC",
+ arm_UHSAX_HI: "UHSAX.HI",
+ arm_UHSAX_LS: "UHSAX.LS",
+ arm_UHSAX_GE: "UHSAX.GE",
+ arm_UHSAX_LT: "UHSAX.LT",
+ arm_UHSAX_GT: "UHSAX.GT",
+ arm_UHSAX_LE: "UHSAX.LE",
+ arm_UHSAX: "UHSAX",
+ arm_UHSAX_ZZ: "UHSAX.ZZ",
+ arm_UHSUB16_EQ: "UHSUB16.EQ",
+ arm_UHSUB16_NE: "UHSUB16.NE",
+ arm_UHSUB16_CS: "UHSUB16.CS",
+ arm_UHSUB16_CC: "UHSUB16.CC",
+ arm_UHSUB16_MI: "UHSUB16.MI",
+ arm_UHSUB16_PL: "UHSUB16.PL",
+ arm_UHSUB16_VS: "UHSUB16.VS",
+ arm_UHSUB16_VC: "UHSUB16.VC",
+ arm_UHSUB16_HI: "UHSUB16.HI",
+ arm_UHSUB16_LS: "UHSUB16.LS",
+ arm_UHSUB16_GE: "UHSUB16.GE",
+ arm_UHSUB16_LT: "UHSUB16.LT",
+ arm_UHSUB16_GT: "UHSUB16.GT",
+ arm_UHSUB16_LE: "UHSUB16.LE",
+ arm_UHSUB16: "UHSUB16",
+ arm_UHSUB16_ZZ: "UHSUB16.ZZ",
+ arm_UHSUB8_EQ: "UHSUB8.EQ",
+ arm_UHSUB8_NE: "UHSUB8.NE",
+ arm_UHSUB8_CS: "UHSUB8.CS",
+ arm_UHSUB8_CC: "UHSUB8.CC",
+ arm_UHSUB8_MI: "UHSUB8.MI",
+ arm_UHSUB8_PL: "UHSUB8.PL",
+ arm_UHSUB8_VS: "UHSUB8.VS",
+ arm_UHSUB8_VC: "UHSUB8.VC",
+ arm_UHSUB8_HI: "UHSUB8.HI",
+ arm_UHSUB8_LS: "UHSUB8.LS",
+ arm_UHSUB8_GE: "UHSUB8.GE",
+ arm_UHSUB8_LT: "UHSUB8.LT",
+ arm_UHSUB8_GT: "UHSUB8.GT",
+ arm_UHSUB8_LE: "UHSUB8.LE",
+ arm_UHSUB8: "UHSUB8",
+ arm_UHSUB8_ZZ: "UHSUB8.ZZ",
+ arm_UMAAL_EQ: "UMAAL.EQ",
+ arm_UMAAL_NE: "UMAAL.NE",
+ arm_UMAAL_CS: "UMAAL.CS",
+ arm_UMAAL_CC: "UMAAL.CC",
+ arm_UMAAL_MI: "UMAAL.MI",
+ arm_UMAAL_PL: "UMAAL.PL",
+ arm_UMAAL_VS: "UMAAL.VS",
+ arm_UMAAL_VC: "UMAAL.VC",
+ arm_UMAAL_HI: "UMAAL.HI",
+ arm_UMAAL_LS: "UMAAL.LS",
+ arm_UMAAL_GE: "UMAAL.GE",
+ arm_UMAAL_LT: "UMAAL.LT",
+ arm_UMAAL_GT: "UMAAL.GT",
+ arm_UMAAL_LE: "UMAAL.LE",
+ arm_UMAAL: "UMAAL",
+ arm_UMAAL_ZZ: "UMAAL.ZZ",
+ arm_UMLAL_EQ: "UMLAL.EQ",
+ arm_UMLAL_NE: "UMLAL.NE",
+ arm_UMLAL_CS: "UMLAL.CS",
+ arm_UMLAL_CC: "UMLAL.CC",
+ arm_UMLAL_MI: "UMLAL.MI",
+ arm_UMLAL_PL: "UMLAL.PL",
+ arm_UMLAL_VS: "UMLAL.VS",
+ arm_UMLAL_VC: "UMLAL.VC",
+ arm_UMLAL_HI: "UMLAL.HI",
+ arm_UMLAL_LS: "UMLAL.LS",
+ arm_UMLAL_GE: "UMLAL.GE",
+ arm_UMLAL_LT: "UMLAL.LT",
+ arm_UMLAL_GT: "UMLAL.GT",
+ arm_UMLAL_LE: "UMLAL.LE",
+ arm_UMLAL: "UMLAL",
+ arm_UMLAL_ZZ: "UMLAL.ZZ",
+ arm_UMLAL_S_EQ: "UMLAL.S.EQ",
+ arm_UMLAL_S_NE: "UMLAL.S.NE",
+ arm_UMLAL_S_CS: "UMLAL.S.CS",
+ arm_UMLAL_S_CC: "UMLAL.S.CC",
+ arm_UMLAL_S_MI: "UMLAL.S.MI",
+ arm_UMLAL_S_PL: "UMLAL.S.PL",
+ arm_UMLAL_S_VS: "UMLAL.S.VS",
+ arm_UMLAL_S_VC: "UMLAL.S.VC",
+ arm_UMLAL_S_HI: "UMLAL.S.HI",
+ arm_UMLAL_S_LS: "UMLAL.S.LS",
+ arm_UMLAL_S_GE: "UMLAL.S.GE",
+ arm_UMLAL_S_LT: "UMLAL.S.LT",
+ arm_UMLAL_S_GT: "UMLAL.S.GT",
+ arm_UMLAL_S_LE: "UMLAL.S.LE",
+ arm_UMLAL_S: "UMLAL.S",
+ arm_UMLAL_S_ZZ: "UMLAL.S.ZZ",
+ arm_UMULL_EQ: "UMULL.EQ",
+ arm_UMULL_NE: "UMULL.NE",
+ arm_UMULL_CS: "UMULL.CS",
+ arm_UMULL_CC: "UMULL.CC",
+ arm_UMULL_MI: "UMULL.MI",
+ arm_UMULL_PL: "UMULL.PL",
+ arm_UMULL_VS: "UMULL.VS",
+ arm_UMULL_VC: "UMULL.VC",
+ arm_UMULL_HI: "UMULL.HI",
+ arm_UMULL_LS: "UMULL.LS",
+ arm_UMULL_GE: "UMULL.GE",
+ arm_UMULL_LT: "UMULL.LT",
+ arm_UMULL_GT: "UMULL.GT",
+ arm_UMULL_LE: "UMULL.LE",
+ arm_UMULL: "UMULL",
+ arm_UMULL_ZZ: "UMULL.ZZ",
+ arm_UMULL_S_EQ: "UMULL.S.EQ",
+ arm_UMULL_S_NE: "UMULL.S.NE",
+ arm_UMULL_S_CS: "UMULL.S.CS",
+ arm_UMULL_S_CC: "UMULL.S.CC",
+ arm_UMULL_S_MI: "UMULL.S.MI",
+ arm_UMULL_S_PL: "UMULL.S.PL",
+ arm_UMULL_S_VS: "UMULL.S.VS",
+ arm_UMULL_S_VC: "UMULL.S.VC",
+ arm_UMULL_S_HI: "UMULL.S.HI",
+ arm_UMULL_S_LS: "UMULL.S.LS",
+ arm_UMULL_S_GE: "UMULL.S.GE",
+ arm_UMULL_S_LT: "UMULL.S.LT",
+ arm_UMULL_S_GT: "UMULL.S.GT",
+ arm_UMULL_S_LE: "UMULL.S.LE",
+ arm_UMULL_S: "UMULL.S",
+ arm_UMULL_S_ZZ: "UMULL.S.ZZ",
+ arm_UNDEF: "UNDEF",
+ arm_UQADD16_EQ: "UQADD16.EQ",
+ arm_UQADD16_NE: "UQADD16.NE",
+ arm_UQADD16_CS: "UQADD16.CS",
+ arm_UQADD16_CC: "UQADD16.CC",
+ arm_UQADD16_MI: "UQADD16.MI",
+ arm_UQADD16_PL: "UQADD16.PL",
+ arm_UQADD16_VS: "UQADD16.VS",
+ arm_UQADD16_VC: "UQADD16.VC",
+ arm_UQADD16_HI: "UQADD16.HI",
+ arm_UQADD16_LS: "UQADD16.LS",
+ arm_UQADD16_GE: "UQADD16.GE",
+ arm_UQADD16_LT: "UQADD16.LT",
+ arm_UQADD16_GT: "UQADD16.GT",
+ arm_UQADD16_LE: "UQADD16.LE",
+ arm_UQADD16: "UQADD16",
+ arm_UQADD16_ZZ: "UQADD16.ZZ",
+ arm_UQADD8_EQ: "UQADD8.EQ",
+ arm_UQADD8_NE: "UQADD8.NE",
+ arm_UQADD8_CS: "UQADD8.CS",
+ arm_UQADD8_CC: "UQADD8.CC",
+ arm_UQADD8_MI: "UQADD8.MI",
+ arm_UQADD8_PL: "UQADD8.PL",
+ arm_UQADD8_VS: "UQADD8.VS",
+ arm_UQADD8_VC: "UQADD8.VC",
+ arm_UQADD8_HI: "UQADD8.HI",
+ arm_UQADD8_LS: "UQADD8.LS",
+ arm_UQADD8_GE: "UQADD8.GE",
+ arm_UQADD8_LT: "UQADD8.LT",
+ arm_UQADD8_GT: "UQADD8.GT",
+ arm_UQADD8_LE: "UQADD8.LE",
+ arm_UQADD8: "UQADD8",
+ arm_UQADD8_ZZ: "UQADD8.ZZ",
+ arm_UQASX_EQ: "UQASX.EQ",
+ arm_UQASX_NE: "UQASX.NE",
+ arm_UQASX_CS: "UQASX.CS",
+ arm_UQASX_CC: "UQASX.CC",
+ arm_UQASX_MI: "UQASX.MI",
+ arm_UQASX_PL: "UQASX.PL",
+ arm_UQASX_VS: "UQASX.VS",
+ arm_UQASX_VC: "UQASX.VC",
+ arm_UQASX_HI: "UQASX.HI",
+ arm_UQASX_LS: "UQASX.LS",
+ arm_UQASX_GE: "UQASX.GE",
+ arm_UQASX_LT: "UQASX.LT",
+ arm_UQASX_GT: "UQASX.GT",
+ arm_UQASX_LE: "UQASX.LE",
+ arm_UQASX: "UQASX",
+ arm_UQASX_ZZ: "UQASX.ZZ",
+ arm_UQSAX_EQ: "UQSAX.EQ",
+ arm_UQSAX_NE: "UQSAX.NE",
+ arm_UQSAX_CS: "UQSAX.CS",
+ arm_UQSAX_CC: "UQSAX.CC",
+ arm_UQSAX_MI: "UQSAX.MI",
+ arm_UQSAX_PL: "UQSAX.PL",
+ arm_UQSAX_VS: "UQSAX.VS",
+ arm_UQSAX_VC: "UQSAX.VC",
+ arm_UQSAX_HI: "UQSAX.HI",
+ arm_UQSAX_LS: "UQSAX.LS",
+ arm_UQSAX_GE: "UQSAX.GE",
+ arm_UQSAX_LT: "UQSAX.LT",
+ arm_UQSAX_GT: "UQSAX.GT",
+ arm_UQSAX_LE: "UQSAX.LE",
+ arm_UQSAX: "UQSAX",
+ arm_UQSAX_ZZ: "UQSAX.ZZ",
+ arm_UQSUB16_EQ: "UQSUB16.EQ",
+ arm_UQSUB16_NE: "UQSUB16.NE",
+ arm_UQSUB16_CS: "UQSUB16.CS",
+ arm_UQSUB16_CC: "UQSUB16.CC",
+ arm_UQSUB16_MI: "UQSUB16.MI",
+ arm_UQSUB16_PL: "UQSUB16.PL",
+ arm_UQSUB16_VS: "UQSUB16.VS",
+ arm_UQSUB16_VC: "UQSUB16.VC",
+ arm_UQSUB16_HI: "UQSUB16.HI",
+ arm_UQSUB16_LS: "UQSUB16.LS",
+ arm_UQSUB16_GE: "UQSUB16.GE",
+ arm_UQSUB16_LT: "UQSUB16.LT",
+ arm_UQSUB16_GT: "UQSUB16.GT",
+ arm_UQSUB16_LE: "UQSUB16.LE",
+ arm_UQSUB16: "UQSUB16",
+ arm_UQSUB16_ZZ: "UQSUB16.ZZ",
+ arm_UQSUB8_EQ: "UQSUB8.EQ",
+ arm_UQSUB8_NE: "UQSUB8.NE",
+ arm_UQSUB8_CS: "UQSUB8.CS",
+ arm_UQSUB8_CC: "UQSUB8.CC",
+ arm_UQSUB8_MI: "UQSUB8.MI",
+ arm_UQSUB8_PL: "UQSUB8.PL",
+ arm_UQSUB8_VS: "UQSUB8.VS",
+ arm_UQSUB8_VC: "UQSUB8.VC",
+ arm_UQSUB8_HI: "UQSUB8.HI",
+ arm_UQSUB8_LS: "UQSUB8.LS",
+ arm_UQSUB8_GE: "UQSUB8.GE",
+ arm_UQSUB8_LT: "UQSUB8.LT",
+ arm_UQSUB8_GT: "UQSUB8.GT",
+ arm_UQSUB8_LE: "UQSUB8.LE",
+ arm_UQSUB8: "UQSUB8",
+ arm_UQSUB8_ZZ: "UQSUB8.ZZ",
+ arm_USAD8_EQ: "USAD8.EQ",
+ arm_USAD8_NE: "USAD8.NE",
+ arm_USAD8_CS: "USAD8.CS",
+ arm_USAD8_CC: "USAD8.CC",
+ arm_USAD8_MI: "USAD8.MI",
+ arm_USAD8_PL: "USAD8.PL",
+ arm_USAD8_VS: "USAD8.VS",
+ arm_USAD8_VC: "USAD8.VC",
+ arm_USAD8_HI: "USAD8.HI",
+ arm_USAD8_LS: "USAD8.LS",
+ arm_USAD8_GE: "USAD8.GE",
+ arm_USAD8_LT: "USAD8.LT",
+ arm_USAD8_GT: "USAD8.GT",
+ arm_USAD8_LE: "USAD8.LE",
+ arm_USAD8: "USAD8",
+ arm_USAD8_ZZ: "USAD8.ZZ",
+ arm_USADA8_EQ: "USADA8.EQ",
+ arm_USADA8_NE: "USADA8.NE",
+ arm_USADA8_CS: "USADA8.CS",
+ arm_USADA8_CC: "USADA8.CC",
+ arm_USADA8_MI: "USADA8.MI",
+ arm_USADA8_PL: "USADA8.PL",
+ arm_USADA8_VS: "USADA8.VS",
+ arm_USADA8_VC: "USADA8.VC",
+ arm_USADA8_HI: "USADA8.HI",
+ arm_USADA8_LS: "USADA8.LS",
+ arm_USADA8_GE: "USADA8.GE",
+ arm_USADA8_LT: "USADA8.LT",
+ arm_USADA8_GT: "USADA8.GT",
+ arm_USADA8_LE: "USADA8.LE",
+ arm_USADA8: "USADA8",
+ arm_USADA8_ZZ: "USADA8.ZZ",
+ arm_USAT_EQ: "USAT.EQ",
+ arm_USAT_NE: "USAT.NE",
+ arm_USAT_CS: "USAT.CS",
+ arm_USAT_CC: "USAT.CC",
+ arm_USAT_MI: "USAT.MI",
+ arm_USAT_PL: "USAT.PL",
+ arm_USAT_VS: "USAT.VS",
+ arm_USAT_VC: "USAT.VC",
+ arm_USAT_HI: "USAT.HI",
+ arm_USAT_LS: "USAT.LS",
+ arm_USAT_GE: "USAT.GE",
+ arm_USAT_LT: "USAT.LT",
+ arm_USAT_GT: "USAT.GT",
+ arm_USAT_LE: "USAT.LE",
+ arm_USAT: "USAT",
+ arm_USAT_ZZ: "USAT.ZZ",
+ arm_USAT16_EQ: "USAT16.EQ",
+ arm_USAT16_NE: "USAT16.NE",
+ arm_USAT16_CS: "USAT16.CS",
+ arm_USAT16_CC: "USAT16.CC",
+ arm_USAT16_MI: "USAT16.MI",
+ arm_USAT16_PL: "USAT16.PL",
+ arm_USAT16_VS: "USAT16.VS",
+ arm_USAT16_VC: "USAT16.VC",
+ arm_USAT16_HI: "USAT16.HI",
+ arm_USAT16_LS: "USAT16.LS",
+ arm_USAT16_GE: "USAT16.GE",
+ arm_USAT16_LT: "USAT16.LT",
+ arm_USAT16_GT: "USAT16.GT",
+ arm_USAT16_LE: "USAT16.LE",
+ arm_USAT16: "USAT16",
+ arm_USAT16_ZZ: "USAT16.ZZ",
+ arm_USAX_EQ: "USAX.EQ",
+ arm_USAX_NE: "USAX.NE",
+ arm_USAX_CS: "USAX.CS",
+ arm_USAX_CC: "USAX.CC",
+ arm_USAX_MI: "USAX.MI",
+ arm_USAX_PL: "USAX.PL",
+ arm_USAX_VS: "USAX.VS",
+ arm_USAX_VC: "USAX.VC",
+ arm_USAX_HI: "USAX.HI",
+ arm_USAX_LS: "USAX.LS",
+ arm_USAX_GE: "USAX.GE",
+ arm_USAX_LT: "USAX.LT",
+ arm_USAX_GT: "USAX.GT",
+ arm_USAX_LE: "USAX.LE",
+ arm_USAX: "USAX",
+ arm_USAX_ZZ: "USAX.ZZ",
+ arm_USUB16_EQ: "USUB16.EQ",
+ arm_USUB16_NE: "USUB16.NE",
+ arm_USUB16_CS: "USUB16.CS",
+ arm_USUB16_CC: "USUB16.CC",
+ arm_USUB16_MI: "USUB16.MI",
+ arm_USUB16_PL: "USUB16.PL",
+ arm_USUB16_VS: "USUB16.VS",
+ arm_USUB16_VC: "USUB16.VC",
+ arm_USUB16_HI: "USUB16.HI",
+ arm_USUB16_LS: "USUB16.LS",
+ arm_USUB16_GE: "USUB16.GE",
+ arm_USUB16_LT: "USUB16.LT",
+ arm_USUB16_GT: "USUB16.GT",
+ arm_USUB16_LE: "USUB16.LE",
+ arm_USUB16: "USUB16",
+ arm_USUB16_ZZ: "USUB16.ZZ",
+ arm_USUB8_EQ: "USUB8.EQ",
+ arm_USUB8_NE: "USUB8.NE",
+ arm_USUB8_CS: "USUB8.CS",
+ arm_USUB8_CC: "USUB8.CC",
+ arm_USUB8_MI: "USUB8.MI",
+ arm_USUB8_PL: "USUB8.PL",
+ arm_USUB8_VS: "USUB8.VS",
+ arm_USUB8_VC: "USUB8.VC",
+ arm_USUB8_HI: "USUB8.HI",
+ arm_USUB8_LS: "USUB8.LS",
+ arm_USUB8_GE: "USUB8.GE",
+ arm_USUB8_LT: "USUB8.LT",
+ arm_USUB8_GT: "USUB8.GT",
+ arm_USUB8_LE: "USUB8.LE",
+ arm_USUB8: "USUB8",
+ arm_USUB8_ZZ: "USUB8.ZZ",
+ arm_UXTAB_EQ: "UXTAB.EQ",
+ arm_UXTAB_NE: "UXTAB.NE",
+ arm_UXTAB_CS: "UXTAB.CS",
+ arm_UXTAB_CC: "UXTAB.CC",
+ arm_UXTAB_MI: "UXTAB.MI",
+ arm_UXTAB_PL: "UXTAB.PL",
+ arm_UXTAB_VS: "UXTAB.VS",
+ arm_UXTAB_VC: "UXTAB.VC",
+ arm_UXTAB_HI: "UXTAB.HI",
+ arm_UXTAB_LS: "UXTAB.LS",
+ arm_UXTAB_GE: "UXTAB.GE",
+ arm_UXTAB_LT: "UXTAB.LT",
+ arm_UXTAB_GT: "UXTAB.GT",
+ arm_UXTAB_LE: "UXTAB.LE",
+ arm_UXTAB: "UXTAB",
+ arm_UXTAB_ZZ: "UXTAB.ZZ",
+ arm_UXTAB16_EQ: "UXTAB16.EQ",
+ arm_UXTAB16_NE: "UXTAB16.NE",
+ arm_UXTAB16_CS: "UXTAB16.CS",
+ arm_UXTAB16_CC: "UXTAB16.CC",
+ arm_UXTAB16_MI: "UXTAB16.MI",
+ arm_UXTAB16_PL: "UXTAB16.PL",
+ arm_UXTAB16_VS: "UXTAB16.VS",
+ arm_UXTAB16_VC: "UXTAB16.VC",
+ arm_UXTAB16_HI: "UXTAB16.HI",
+ arm_UXTAB16_LS: "UXTAB16.LS",
+ arm_UXTAB16_GE: "UXTAB16.GE",
+ arm_UXTAB16_LT: "UXTAB16.LT",
+ arm_UXTAB16_GT: "UXTAB16.GT",
+ arm_UXTAB16_LE: "UXTAB16.LE",
+ arm_UXTAB16: "UXTAB16",
+ arm_UXTAB16_ZZ: "UXTAB16.ZZ",
+ arm_UXTAH_EQ: "UXTAH.EQ",
+ arm_UXTAH_NE: "UXTAH.NE",
+ arm_UXTAH_CS: "UXTAH.CS",
+ arm_UXTAH_CC: "UXTAH.CC",
+ arm_UXTAH_MI: "UXTAH.MI",
+ arm_UXTAH_PL: "UXTAH.PL",
+ arm_UXTAH_VS: "UXTAH.VS",
+ arm_UXTAH_VC: "UXTAH.VC",
+ arm_UXTAH_HI: "UXTAH.HI",
+ arm_UXTAH_LS: "UXTAH.LS",
+ arm_UXTAH_GE: "UXTAH.GE",
+ arm_UXTAH_LT: "UXTAH.LT",
+ arm_UXTAH_GT: "UXTAH.GT",
+ arm_UXTAH_LE: "UXTAH.LE",
+ arm_UXTAH: "UXTAH",
+ arm_UXTAH_ZZ: "UXTAH.ZZ",
+ arm_UXTB_EQ: "UXTB.EQ",
+ arm_UXTB_NE: "UXTB.NE",
+ arm_UXTB_CS: "UXTB.CS",
+ arm_UXTB_CC: "UXTB.CC",
+ arm_UXTB_MI: "UXTB.MI",
+ arm_UXTB_PL: "UXTB.PL",
+ arm_UXTB_VS: "UXTB.VS",
+ arm_UXTB_VC: "UXTB.VC",
+ arm_UXTB_HI: "UXTB.HI",
+ arm_UXTB_LS: "UXTB.LS",
+ arm_UXTB_GE: "UXTB.GE",
+ arm_UXTB_LT: "UXTB.LT",
+ arm_UXTB_GT: "UXTB.GT",
+ arm_UXTB_LE: "UXTB.LE",
+ arm_UXTB: "UXTB",
+ arm_UXTB_ZZ: "UXTB.ZZ",
+ arm_UXTB16_EQ: "UXTB16.EQ",
+ arm_UXTB16_NE: "UXTB16.NE",
+ arm_UXTB16_CS: "UXTB16.CS",
+ arm_UXTB16_CC: "UXTB16.CC",
+ arm_UXTB16_MI: "UXTB16.MI",
+ arm_UXTB16_PL: "UXTB16.PL",
+ arm_UXTB16_VS: "UXTB16.VS",
+ arm_UXTB16_VC: "UXTB16.VC",
+ arm_UXTB16_HI: "UXTB16.HI",
+ arm_UXTB16_LS: "UXTB16.LS",
+ arm_UXTB16_GE: "UXTB16.GE",
+ arm_UXTB16_LT: "UXTB16.LT",
+ arm_UXTB16_GT: "UXTB16.GT",
+ arm_UXTB16_LE: "UXTB16.LE",
+ arm_UXTB16: "UXTB16",
+ arm_UXTB16_ZZ: "UXTB16.ZZ",
+ arm_UXTH_EQ: "UXTH.EQ",
+ arm_UXTH_NE: "UXTH.NE",
+ arm_UXTH_CS: "UXTH.CS",
+ arm_UXTH_CC: "UXTH.CC",
+ arm_UXTH_MI: "UXTH.MI",
+ arm_UXTH_PL: "UXTH.PL",
+ arm_UXTH_VS: "UXTH.VS",
+ arm_UXTH_VC: "UXTH.VC",
+ arm_UXTH_HI: "UXTH.HI",
+ arm_UXTH_LS: "UXTH.LS",
+ arm_UXTH_GE: "UXTH.GE",
+ arm_UXTH_LT: "UXTH.LT",
+ arm_UXTH_GT: "UXTH.GT",
+ arm_UXTH_LE: "UXTH.LE",
+ arm_UXTH: "UXTH",
+ arm_UXTH_ZZ: "UXTH.ZZ",
+ arm_VABS_EQ_F32: "VABS.EQ.F32",
+ arm_VABS_NE_F32: "VABS.NE.F32",
+ arm_VABS_CS_F32: "VABS.CS.F32",
+ arm_VABS_CC_F32: "VABS.CC.F32",
+ arm_VABS_MI_F32: "VABS.MI.F32",
+ arm_VABS_PL_F32: "VABS.PL.F32",
+ arm_VABS_VS_F32: "VABS.VS.F32",
+ arm_VABS_VC_F32: "VABS.VC.F32",
+ arm_VABS_HI_F32: "VABS.HI.F32",
+ arm_VABS_LS_F32: "VABS.LS.F32",
+ arm_VABS_GE_F32: "VABS.GE.F32",
+ arm_VABS_LT_F32: "VABS.LT.F32",
+ arm_VABS_GT_F32: "VABS.GT.F32",
+ arm_VABS_LE_F32: "VABS.LE.F32",
+ arm_VABS_F32: "VABS.F32",
+ arm_VABS_ZZ_F32: "VABS.ZZ.F32",
+ arm_VABS_EQ_F64: "VABS.EQ.F64",
+ arm_VABS_NE_F64: "VABS.NE.F64",
+ arm_VABS_CS_F64: "VABS.CS.F64",
+ arm_VABS_CC_F64: "VABS.CC.F64",
+ arm_VABS_MI_F64: "VABS.MI.F64",
+ arm_VABS_PL_F64: "VABS.PL.F64",
+ arm_VABS_VS_F64: "VABS.VS.F64",
+ arm_VABS_VC_F64: "VABS.VC.F64",
+ arm_VABS_HI_F64: "VABS.HI.F64",
+ arm_VABS_LS_F64: "VABS.LS.F64",
+ arm_VABS_GE_F64: "VABS.GE.F64",
+ arm_VABS_LT_F64: "VABS.LT.F64",
+ arm_VABS_GT_F64: "VABS.GT.F64",
+ arm_VABS_LE_F64: "VABS.LE.F64",
+ arm_VABS_F64: "VABS.F64",
+ arm_VABS_ZZ_F64: "VABS.ZZ.F64",
+ arm_VADD_EQ_F32: "VADD.EQ.F32",
+ arm_VADD_NE_F32: "VADD.NE.F32",
+ arm_VADD_CS_F32: "VADD.CS.F32",
+ arm_VADD_CC_F32: "VADD.CC.F32",
+ arm_VADD_MI_F32: "VADD.MI.F32",
+ arm_VADD_PL_F32: "VADD.PL.F32",
+ arm_VADD_VS_F32: "VADD.VS.F32",
+ arm_VADD_VC_F32: "VADD.VC.F32",
+ arm_VADD_HI_F32: "VADD.HI.F32",
+ arm_VADD_LS_F32: "VADD.LS.F32",
+ arm_VADD_GE_F32: "VADD.GE.F32",
+ arm_VADD_LT_F32: "VADD.LT.F32",
+ arm_VADD_GT_F32: "VADD.GT.F32",
+ arm_VADD_LE_F32: "VADD.LE.F32",
+ arm_VADD_F32: "VADD.F32",
+ arm_VADD_ZZ_F32: "VADD.ZZ.F32",
+ arm_VADD_EQ_F64: "VADD.EQ.F64",
+ arm_VADD_NE_F64: "VADD.NE.F64",
+ arm_VADD_CS_F64: "VADD.CS.F64",
+ arm_VADD_CC_F64: "VADD.CC.F64",
+ arm_VADD_MI_F64: "VADD.MI.F64",
+ arm_VADD_PL_F64: "VADD.PL.F64",
+ arm_VADD_VS_F64: "VADD.VS.F64",
+ arm_VADD_VC_F64: "VADD.VC.F64",
+ arm_VADD_HI_F64: "VADD.HI.F64",
+ arm_VADD_LS_F64: "VADD.LS.F64",
+ arm_VADD_GE_F64: "VADD.GE.F64",
+ arm_VADD_LT_F64: "VADD.LT.F64",
+ arm_VADD_GT_F64: "VADD.GT.F64",
+ arm_VADD_LE_F64: "VADD.LE.F64",
+ arm_VADD_F64: "VADD.F64",
+ arm_VADD_ZZ_F64: "VADD.ZZ.F64",
+ arm_VCMP_EQ_F32: "VCMP.EQ.F32",
+ arm_VCMP_NE_F32: "VCMP.NE.F32",
+ arm_VCMP_CS_F32: "VCMP.CS.F32",
+ arm_VCMP_CC_F32: "VCMP.CC.F32",
+ arm_VCMP_MI_F32: "VCMP.MI.F32",
+ arm_VCMP_PL_F32: "VCMP.PL.F32",
+ arm_VCMP_VS_F32: "VCMP.VS.F32",
+ arm_VCMP_VC_F32: "VCMP.VC.F32",
+ arm_VCMP_HI_F32: "VCMP.HI.F32",
+ arm_VCMP_LS_F32: "VCMP.LS.F32",
+ arm_VCMP_GE_F32: "VCMP.GE.F32",
+ arm_VCMP_LT_F32: "VCMP.LT.F32",
+ arm_VCMP_GT_F32: "VCMP.GT.F32",
+ arm_VCMP_LE_F32: "VCMP.LE.F32",
+ arm_VCMP_F32: "VCMP.F32",
+ arm_VCMP_ZZ_F32: "VCMP.ZZ.F32",
+ arm_VCMP_EQ_F64: "VCMP.EQ.F64",
+ arm_VCMP_NE_F64: "VCMP.NE.F64",
+ arm_VCMP_CS_F64: "VCMP.CS.F64",
+ arm_VCMP_CC_F64: "VCMP.CC.F64",
+ arm_VCMP_MI_F64: "VCMP.MI.F64",
+ arm_VCMP_PL_F64: "VCMP.PL.F64",
+ arm_VCMP_VS_F64: "VCMP.VS.F64",
+ arm_VCMP_VC_F64: "VCMP.VC.F64",
+ arm_VCMP_HI_F64: "VCMP.HI.F64",
+ arm_VCMP_LS_F64: "VCMP.LS.F64",
+ arm_VCMP_GE_F64: "VCMP.GE.F64",
+ arm_VCMP_LT_F64: "VCMP.LT.F64",
+ arm_VCMP_GT_F64: "VCMP.GT.F64",
+ arm_VCMP_LE_F64: "VCMP.LE.F64",
+ arm_VCMP_F64: "VCMP.F64",
+ arm_VCMP_ZZ_F64: "VCMP.ZZ.F64",
+ arm_VCMP_E_EQ_F32: "VCMP.E.EQ.F32",
+ arm_VCMP_E_NE_F32: "VCMP.E.NE.F32",
+ arm_VCMP_E_CS_F32: "VCMP.E.CS.F32",
+ arm_VCMP_E_CC_F32: "VCMP.E.CC.F32",
+ arm_VCMP_E_MI_F32: "VCMP.E.MI.F32",
+ arm_VCMP_E_PL_F32: "VCMP.E.PL.F32",
+ arm_VCMP_E_VS_F32: "VCMP.E.VS.F32",
+ arm_VCMP_E_VC_F32: "VCMP.E.VC.F32",
+ arm_VCMP_E_HI_F32: "VCMP.E.HI.F32",
+ arm_VCMP_E_LS_F32: "VCMP.E.LS.F32",
+ arm_VCMP_E_GE_F32: "VCMP.E.GE.F32",
+ arm_VCMP_E_LT_F32: "VCMP.E.LT.F32",
+ arm_VCMP_E_GT_F32: "VCMP.E.GT.F32",
+ arm_VCMP_E_LE_F32: "VCMP.E.LE.F32",
+ arm_VCMP_E_F32: "VCMP.E.F32",
+ arm_VCMP_E_ZZ_F32: "VCMP.E.ZZ.F32",
+ arm_VCMP_E_EQ_F64: "VCMP.E.EQ.F64",
+ arm_VCMP_E_NE_F64: "VCMP.E.NE.F64",
+ arm_VCMP_E_CS_F64: "VCMP.E.CS.F64",
+ arm_VCMP_E_CC_F64: "VCMP.E.CC.F64",
+ arm_VCMP_E_MI_F64: "VCMP.E.MI.F64",
+ arm_VCMP_E_PL_F64: "VCMP.E.PL.F64",
+ arm_VCMP_E_VS_F64: "VCMP.E.VS.F64",
+ arm_VCMP_E_VC_F64: "VCMP.E.VC.F64",
+ arm_VCMP_E_HI_F64: "VCMP.E.HI.F64",
+ arm_VCMP_E_LS_F64: "VCMP.E.LS.F64",
+ arm_VCMP_E_GE_F64: "VCMP.E.GE.F64",
+ arm_VCMP_E_LT_F64: "VCMP.E.LT.F64",
+ arm_VCMP_E_GT_F64: "VCMP.E.GT.F64",
+ arm_VCMP_E_LE_F64: "VCMP.E.LE.F64",
+ arm_VCMP_E_F64: "VCMP.E.F64",
+ arm_VCMP_E_ZZ_F64: "VCMP.E.ZZ.F64",
+ arm_VCVT_EQ_F32_FXS16: "VCVT.EQ.F32.FXS16",
+ arm_VCVT_NE_F32_FXS16: "VCVT.NE.F32.FXS16",
+ arm_VCVT_CS_F32_FXS16: "VCVT.CS.F32.FXS16",
+ arm_VCVT_CC_F32_FXS16: "VCVT.CC.F32.FXS16",
+ arm_VCVT_MI_F32_FXS16: "VCVT.MI.F32.FXS16",
+ arm_VCVT_PL_F32_FXS16: "VCVT.PL.F32.FXS16",
+ arm_VCVT_VS_F32_FXS16: "VCVT.VS.F32.FXS16",
+ arm_VCVT_VC_F32_FXS16: "VCVT.VC.F32.FXS16",
+ arm_VCVT_HI_F32_FXS16: "VCVT.HI.F32.FXS16",
+ arm_VCVT_LS_F32_FXS16: "VCVT.LS.F32.FXS16",
+ arm_VCVT_GE_F32_FXS16: "VCVT.GE.F32.FXS16",
+ arm_VCVT_LT_F32_FXS16: "VCVT.LT.F32.FXS16",
+ arm_VCVT_GT_F32_FXS16: "VCVT.GT.F32.FXS16",
+ arm_VCVT_LE_F32_FXS16: "VCVT.LE.F32.FXS16",
+ arm_VCVT_F32_FXS16: "VCVT.F32.FXS16",
+ arm_VCVT_ZZ_F32_FXS16: "VCVT.ZZ.F32.FXS16",
+ arm_VCVT_EQ_F32_FXS32: "VCVT.EQ.F32.FXS32",
+ arm_VCVT_NE_F32_FXS32: "VCVT.NE.F32.FXS32",
+ arm_VCVT_CS_F32_FXS32: "VCVT.CS.F32.FXS32",
+ arm_VCVT_CC_F32_FXS32: "VCVT.CC.F32.FXS32",
+ arm_VCVT_MI_F32_FXS32: "VCVT.MI.F32.FXS32",
+ arm_VCVT_PL_F32_FXS32: "VCVT.PL.F32.FXS32",
+ arm_VCVT_VS_F32_FXS32: "VCVT.VS.F32.FXS32",
+ arm_VCVT_VC_F32_FXS32: "VCVT.VC.F32.FXS32",
+ arm_VCVT_HI_F32_FXS32: "VCVT.HI.F32.FXS32",
+ arm_VCVT_LS_F32_FXS32: "VCVT.LS.F32.FXS32",
+ arm_VCVT_GE_F32_FXS32: "VCVT.GE.F32.FXS32",
+ arm_VCVT_LT_F32_FXS32: "VCVT.LT.F32.FXS32",
+ arm_VCVT_GT_F32_FXS32: "VCVT.GT.F32.FXS32",
+ arm_VCVT_LE_F32_FXS32: "VCVT.LE.F32.FXS32",
+ arm_VCVT_F32_FXS32: "VCVT.F32.FXS32",
+ arm_VCVT_ZZ_F32_FXS32: "VCVT.ZZ.F32.FXS32",
+ arm_VCVT_EQ_F32_FXU16: "VCVT.EQ.F32.FXU16",
+ arm_VCVT_NE_F32_FXU16: "VCVT.NE.F32.FXU16",
+ arm_VCVT_CS_F32_FXU16: "VCVT.CS.F32.FXU16",
+ arm_VCVT_CC_F32_FXU16: "VCVT.CC.F32.FXU16",
+ arm_VCVT_MI_F32_FXU16: "VCVT.MI.F32.FXU16",
+ arm_VCVT_PL_F32_FXU16: "VCVT.PL.F32.FXU16",
+ arm_VCVT_VS_F32_FXU16: "VCVT.VS.F32.FXU16",
+ arm_VCVT_VC_F32_FXU16: "VCVT.VC.F32.FXU16",
+ arm_VCVT_HI_F32_FXU16: "VCVT.HI.F32.FXU16",
+ arm_VCVT_LS_F32_FXU16: "VCVT.LS.F32.FXU16",
+ arm_VCVT_GE_F32_FXU16: "VCVT.GE.F32.FXU16",
+ arm_VCVT_LT_F32_FXU16: "VCVT.LT.F32.FXU16",
+ arm_VCVT_GT_F32_FXU16: "VCVT.GT.F32.FXU16",
+ arm_VCVT_LE_F32_FXU16: "VCVT.LE.F32.FXU16",
+ arm_VCVT_F32_FXU16: "VCVT.F32.FXU16",
+ arm_VCVT_ZZ_F32_FXU16: "VCVT.ZZ.F32.FXU16",
+ arm_VCVT_EQ_F32_FXU32: "VCVT.EQ.F32.FXU32",
+ arm_VCVT_NE_F32_FXU32: "VCVT.NE.F32.FXU32",
+ arm_VCVT_CS_F32_FXU32: "VCVT.CS.F32.FXU32",
+ arm_VCVT_CC_F32_FXU32: "VCVT.CC.F32.FXU32",
+ arm_VCVT_MI_F32_FXU32: "VCVT.MI.F32.FXU32",
+ arm_VCVT_PL_F32_FXU32: "VCVT.PL.F32.FXU32",
+ arm_VCVT_VS_F32_FXU32: "VCVT.VS.F32.FXU32",
+ arm_VCVT_VC_F32_FXU32: "VCVT.VC.F32.FXU32",
+ arm_VCVT_HI_F32_FXU32: "VCVT.HI.F32.FXU32",
+ arm_VCVT_LS_F32_FXU32: "VCVT.LS.F32.FXU32",
+ arm_VCVT_GE_F32_FXU32: "VCVT.GE.F32.FXU32",
+ arm_VCVT_LT_F32_FXU32: "VCVT.LT.F32.FXU32",
+ arm_VCVT_GT_F32_FXU32: "VCVT.GT.F32.FXU32",
+ arm_VCVT_LE_F32_FXU32: "VCVT.LE.F32.FXU32",
+ arm_VCVT_F32_FXU32: "VCVT.F32.FXU32",
+ arm_VCVT_ZZ_F32_FXU32: "VCVT.ZZ.F32.FXU32",
+ arm_VCVT_EQ_F64_FXS16: "VCVT.EQ.F64.FXS16",
+ arm_VCVT_NE_F64_FXS16: "VCVT.NE.F64.FXS16",
+ arm_VCVT_CS_F64_FXS16: "VCVT.CS.F64.FXS16",
+ arm_VCVT_CC_F64_FXS16: "VCVT.CC.F64.FXS16",
+ arm_VCVT_MI_F64_FXS16: "VCVT.MI.F64.FXS16",
+ arm_VCVT_PL_F64_FXS16: "VCVT.PL.F64.FXS16",
+ arm_VCVT_VS_F64_FXS16: "VCVT.VS.F64.FXS16",
+ arm_VCVT_VC_F64_FXS16: "VCVT.VC.F64.FXS16",
+ arm_VCVT_HI_F64_FXS16: "VCVT.HI.F64.FXS16",
+ arm_VCVT_LS_F64_FXS16: "VCVT.LS.F64.FXS16",
+ arm_VCVT_GE_F64_FXS16: "VCVT.GE.F64.FXS16",
+ arm_VCVT_LT_F64_FXS16: "VCVT.LT.F64.FXS16",
+ arm_VCVT_GT_F64_FXS16: "VCVT.GT.F64.FXS16",
+ arm_VCVT_LE_F64_FXS16: "VCVT.LE.F64.FXS16",
+ arm_VCVT_F64_FXS16: "VCVT.F64.FXS16",
+ arm_VCVT_ZZ_F64_FXS16: "VCVT.ZZ.F64.FXS16",
+ arm_VCVT_EQ_F64_FXS32: "VCVT.EQ.F64.FXS32",
+ arm_VCVT_NE_F64_FXS32: "VCVT.NE.F64.FXS32",
+ arm_VCVT_CS_F64_FXS32: "VCVT.CS.F64.FXS32",
+ arm_VCVT_CC_F64_FXS32: "VCVT.CC.F64.FXS32",
+ arm_VCVT_MI_F64_FXS32: "VCVT.MI.F64.FXS32",
+ arm_VCVT_PL_F64_FXS32: "VCVT.PL.F64.FXS32",
+ arm_VCVT_VS_F64_FXS32: "VCVT.VS.F64.FXS32",
+ arm_VCVT_VC_F64_FXS32: "VCVT.VC.F64.FXS32",
+ arm_VCVT_HI_F64_FXS32: "VCVT.HI.F64.FXS32",
+ arm_VCVT_LS_F64_FXS32: "VCVT.LS.F64.FXS32",
+ arm_VCVT_GE_F64_FXS32: "VCVT.GE.F64.FXS32",
+ arm_VCVT_LT_F64_FXS32: "VCVT.LT.F64.FXS32",
+ arm_VCVT_GT_F64_FXS32: "VCVT.GT.F64.FXS32",
+ arm_VCVT_LE_F64_FXS32: "VCVT.LE.F64.FXS32",
+ arm_VCVT_F64_FXS32: "VCVT.F64.FXS32",
+ arm_VCVT_ZZ_F64_FXS32: "VCVT.ZZ.F64.FXS32",
+ arm_VCVT_EQ_F64_FXU16: "VCVT.EQ.F64.FXU16",
+ arm_VCVT_NE_F64_FXU16: "VCVT.NE.F64.FXU16",
+ arm_VCVT_CS_F64_FXU16: "VCVT.CS.F64.FXU16",
+ arm_VCVT_CC_F64_FXU16: "VCVT.CC.F64.FXU16",
+ arm_VCVT_MI_F64_FXU16: "VCVT.MI.F64.FXU16",
+ arm_VCVT_PL_F64_FXU16: "VCVT.PL.F64.FXU16",
+ arm_VCVT_VS_F64_FXU16: "VCVT.VS.F64.FXU16",
+ arm_VCVT_VC_F64_FXU16: "VCVT.VC.F64.FXU16",
+ arm_VCVT_HI_F64_FXU16: "VCVT.HI.F64.FXU16",
+ arm_VCVT_LS_F64_FXU16: "VCVT.LS.F64.FXU16",
+ arm_VCVT_GE_F64_FXU16: "VCVT.GE.F64.FXU16",
+ arm_VCVT_LT_F64_FXU16: "VCVT.LT.F64.FXU16",
+ arm_VCVT_GT_F64_FXU16: "VCVT.GT.F64.FXU16",
+ arm_VCVT_LE_F64_FXU16: "VCVT.LE.F64.FXU16",
+ arm_VCVT_F64_FXU16: "VCVT.F64.FXU16",
+ arm_VCVT_ZZ_F64_FXU16: "VCVT.ZZ.F64.FXU16",
+ arm_VCVT_EQ_F64_FXU32: "VCVT.EQ.F64.FXU32",
+ arm_VCVT_NE_F64_FXU32: "VCVT.NE.F64.FXU32",
+ arm_VCVT_CS_F64_FXU32: "VCVT.CS.F64.FXU32",
+ arm_VCVT_CC_F64_FXU32: "VCVT.CC.F64.FXU32",
+ arm_VCVT_MI_F64_FXU32: "VCVT.MI.F64.FXU32",
+ arm_VCVT_PL_F64_FXU32: "VCVT.PL.F64.FXU32",
+ arm_VCVT_VS_F64_FXU32: "VCVT.VS.F64.FXU32",
+ arm_VCVT_VC_F64_FXU32: "VCVT.VC.F64.FXU32",
+ arm_VCVT_HI_F64_FXU32: "VCVT.HI.F64.FXU32",
+ arm_VCVT_LS_F64_FXU32: "VCVT.LS.F64.FXU32",
+ arm_VCVT_GE_F64_FXU32: "VCVT.GE.F64.FXU32",
+ arm_VCVT_LT_F64_FXU32: "VCVT.LT.F64.FXU32",
+ arm_VCVT_GT_F64_FXU32: "VCVT.GT.F64.FXU32",
+ arm_VCVT_LE_F64_FXU32: "VCVT.LE.F64.FXU32",
+ arm_VCVT_F64_FXU32: "VCVT.F64.FXU32",
+ arm_VCVT_ZZ_F64_FXU32: "VCVT.ZZ.F64.FXU32",
+ arm_VCVT_EQ_F32_U32: "VCVT.EQ.F32.U32",
+ arm_VCVT_NE_F32_U32: "VCVT.NE.F32.U32",
+ arm_VCVT_CS_F32_U32: "VCVT.CS.F32.U32",
+ arm_VCVT_CC_F32_U32: "VCVT.CC.F32.U32",
+ arm_VCVT_MI_F32_U32: "VCVT.MI.F32.U32",
+ arm_VCVT_PL_F32_U32: "VCVT.PL.F32.U32",
+ arm_VCVT_VS_F32_U32: "VCVT.VS.F32.U32",
+ arm_VCVT_VC_F32_U32: "VCVT.VC.F32.U32",
+ arm_VCVT_HI_F32_U32: "VCVT.HI.F32.U32",
+ arm_VCVT_LS_F32_U32: "VCVT.LS.F32.U32",
+ arm_VCVT_GE_F32_U32: "VCVT.GE.F32.U32",
+ arm_VCVT_LT_F32_U32: "VCVT.LT.F32.U32",
+ arm_VCVT_GT_F32_U32: "VCVT.GT.F32.U32",
+ arm_VCVT_LE_F32_U32: "VCVT.LE.F32.U32",
+ arm_VCVT_F32_U32: "VCVT.F32.U32",
+ arm_VCVT_ZZ_F32_U32: "VCVT.ZZ.F32.U32",
+ arm_VCVT_EQ_F32_S32: "VCVT.EQ.F32.S32",
+ arm_VCVT_NE_F32_S32: "VCVT.NE.F32.S32",
+ arm_VCVT_CS_F32_S32: "VCVT.CS.F32.S32",
+ arm_VCVT_CC_F32_S32: "VCVT.CC.F32.S32",
+ arm_VCVT_MI_F32_S32: "VCVT.MI.F32.S32",
+ arm_VCVT_PL_F32_S32: "VCVT.PL.F32.S32",
+ arm_VCVT_VS_F32_S32: "VCVT.VS.F32.S32",
+ arm_VCVT_VC_F32_S32: "VCVT.VC.F32.S32",
+ arm_VCVT_HI_F32_S32: "VCVT.HI.F32.S32",
+ arm_VCVT_LS_F32_S32: "VCVT.LS.F32.S32",
+ arm_VCVT_GE_F32_S32: "VCVT.GE.F32.S32",
+ arm_VCVT_LT_F32_S32: "VCVT.LT.F32.S32",
+ arm_VCVT_GT_F32_S32: "VCVT.GT.F32.S32",
+ arm_VCVT_LE_F32_S32: "VCVT.LE.F32.S32",
+ arm_VCVT_F32_S32: "VCVT.F32.S32",
+ arm_VCVT_ZZ_F32_S32: "VCVT.ZZ.F32.S32",
+ arm_VCVT_EQ_F64_U32: "VCVT.EQ.F64.U32",
+ arm_VCVT_NE_F64_U32: "VCVT.NE.F64.U32",
+ arm_VCVT_CS_F64_U32: "VCVT.CS.F64.U32",
+ arm_VCVT_CC_F64_U32: "VCVT.CC.F64.U32",
+ arm_VCVT_MI_F64_U32: "VCVT.MI.F64.U32",
+ arm_VCVT_PL_F64_U32: "VCVT.PL.F64.U32",
+ arm_VCVT_VS_F64_U32: "VCVT.VS.F64.U32",
+ arm_VCVT_VC_F64_U32: "VCVT.VC.F64.U32",
+ arm_VCVT_HI_F64_U32: "VCVT.HI.F64.U32",
+ arm_VCVT_LS_F64_U32: "VCVT.LS.F64.U32",
+ arm_VCVT_GE_F64_U32: "VCVT.GE.F64.U32",
+ arm_VCVT_LT_F64_U32: "VCVT.LT.F64.U32",
+ arm_VCVT_GT_F64_U32: "VCVT.GT.F64.U32",
+ arm_VCVT_LE_F64_U32: "VCVT.LE.F64.U32",
+ arm_VCVT_F64_U32: "VCVT.F64.U32",
+ arm_VCVT_ZZ_F64_U32: "VCVT.ZZ.F64.U32",
+ arm_VCVT_EQ_F64_S32: "VCVT.EQ.F64.S32",
+ arm_VCVT_NE_F64_S32: "VCVT.NE.F64.S32",
+ arm_VCVT_CS_F64_S32: "VCVT.CS.F64.S32",
+ arm_VCVT_CC_F64_S32: "VCVT.CC.F64.S32",
+ arm_VCVT_MI_F64_S32: "VCVT.MI.F64.S32",
+ arm_VCVT_PL_F64_S32: "VCVT.PL.F64.S32",
+ arm_VCVT_VS_F64_S32: "VCVT.VS.F64.S32",
+ arm_VCVT_VC_F64_S32: "VCVT.VC.F64.S32",
+ arm_VCVT_HI_F64_S32: "VCVT.HI.F64.S32",
+ arm_VCVT_LS_F64_S32: "VCVT.LS.F64.S32",
+ arm_VCVT_GE_F64_S32: "VCVT.GE.F64.S32",
+ arm_VCVT_LT_F64_S32: "VCVT.LT.F64.S32",
+ arm_VCVT_GT_F64_S32: "VCVT.GT.F64.S32",
+ arm_VCVT_LE_F64_S32: "VCVT.LE.F64.S32",
+ arm_VCVT_F64_S32: "VCVT.F64.S32",
+ arm_VCVT_ZZ_F64_S32: "VCVT.ZZ.F64.S32",
+ arm_VCVT_EQ_F64_F32: "VCVT.EQ.F64.F32",
+ arm_VCVT_NE_F64_F32: "VCVT.NE.F64.F32",
+ arm_VCVT_CS_F64_F32: "VCVT.CS.F64.F32",
+ arm_VCVT_CC_F64_F32: "VCVT.CC.F64.F32",
+ arm_VCVT_MI_F64_F32: "VCVT.MI.F64.F32",
+ arm_VCVT_PL_F64_F32: "VCVT.PL.F64.F32",
+ arm_VCVT_VS_F64_F32: "VCVT.VS.F64.F32",
+ arm_VCVT_VC_F64_F32: "VCVT.VC.F64.F32",
+ arm_VCVT_HI_F64_F32: "VCVT.HI.F64.F32",
+ arm_VCVT_LS_F64_F32: "VCVT.LS.F64.F32",
+ arm_VCVT_GE_F64_F32: "VCVT.GE.F64.F32",
+ arm_VCVT_LT_F64_F32: "VCVT.LT.F64.F32",
+ arm_VCVT_GT_F64_F32: "VCVT.GT.F64.F32",
+ arm_VCVT_LE_F64_F32: "VCVT.LE.F64.F32",
+ arm_VCVT_F64_F32: "VCVT.F64.F32",
+ arm_VCVT_ZZ_F64_F32: "VCVT.ZZ.F64.F32",
+ arm_VCVT_EQ_F32_F64: "VCVT.EQ.F32.F64",
+ arm_VCVT_NE_F32_F64: "VCVT.NE.F32.F64",
+ arm_VCVT_CS_F32_F64: "VCVT.CS.F32.F64",
+ arm_VCVT_CC_F32_F64: "VCVT.CC.F32.F64",
+ arm_VCVT_MI_F32_F64: "VCVT.MI.F32.F64",
+ arm_VCVT_PL_F32_F64: "VCVT.PL.F32.F64",
+ arm_VCVT_VS_F32_F64: "VCVT.VS.F32.F64",
+ arm_VCVT_VC_F32_F64: "VCVT.VC.F32.F64",
+ arm_VCVT_HI_F32_F64: "VCVT.HI.F32.F64",
+ arm_VCVT_LS_F32_F64: "VCVT.LS.F32.F64",
+ arm_VCVT_GE_F32_F64: "VCVT.GE.F32.F64",
+ arm_VCVT_LT_F32_F64: "VCVT.LT.F32.F64",
+ arm_VCVT_GT_F32_F64: "VCVT.GT.F32.F64",
+ arm_VCVT_LE_F32_F64: "VCVT.LE.F32.F64",
+ arm_VCVT_F32_F64: "VCVT.F32.F64",
+ arm_VCVT_ZZ_F32_F64: "VCVT.ZZ.F32.F64",
+ arm_VCVT_EQ_FXS16_F32: "VCVT.EQ.FXS16.F32",
+ arm_VCVT_NE_FXS16_F32: "VCVT.NE.FXS16.F32",
+ arm_VCVT_CS_FXS16_F32: "VCVT.CS.FXS16.F32",
+ arm_VCVT_CC_FXS16_F32: "VCVT.CC.FXS16.F32",
+ arm_VCVT_MI_FXS16_F32: "VCVT.MI.FXS16.F32",
+ arm_VCVT_PL_FXS16_F32: "VCVT.PL.FXS16.F32",
+ arm_VCVT_VS_FXS16_F32: "VCVT.VS.FXS16.F32",
+ arm_VCVT_VC_FXS16_F32: "VCVT.VC.FXS16.F32",
+ arm_VCVT_HI_FXS16_F32: "VCVT.HI.FXS16.F32",
+ arm_VCVT_LS_FXS16_F32: "VCVT.LS.FXS16.F32",
+ arm_VCVT_GE_FXS16_F32: "VCVT.GE.FXS16.F32",
+ arm_VCVT_LT_FXS16_F32: "VCVT.LT.FXS16.F32",
+ arm_VCVT_GT_FXS16_F32: "VCVT.GT.FXS16.F32",
+ arm_VCVT_LE_FXS16_F32: "VCVT.LE.FXS16.F32",
+ arm_VCVT_FXS16_F32: "VCVT.FXS16.F32",
+ arm_VCVT_ZZ_FXS16_F32: "VCVT.ZZ.FXS16.F32",
+ arm_VCVT_EQ_FXS16_F64: "VCVT.EQ.FXS16.F64",
+ arm_VCVT_NE_FXS16_F64: "VCVT.NE.FXS16.F64",
+ arm_VCVT_CS_FXS16_F64: "VCVT.CS.FXS16.F64",
+ arm_VCVT_CC_FXS16_F64: "VCVT.CC.FXS16.F64",
+ arm_VCVT_MI_FXS16_F64: "VCVT.MI.FXS16.F64",
+ arm_VCVT_PL_FXS16_F64: "VCVT.PL.FXS16.F64",
+ arm_VCVT_VS_FXS16_F64: "VCVT.VS.FXS16.F64",
+ arm_VCVT_VC_FXS16_F64: "VCVT.VC.FXS16.F64",
+ arm_VCVT_HI_FXS16_F64: "VCVT.HI.FXS16.F64",
+ arm_VCVT_LS_FXS16_F64: "VCVT.LS.FXS16.F64",
+ arm_VCVT_GE_FXS16_F64: "VCVT.GE.FXS16.F64",
+ arm_VCVT_LT_FXS16_F64: "VCVT.LT.FXS16.F64",
+ arm_VCVT_GT_FXS16_F64: "VCVT.GT.FXS16.F64",
+ arm_VCVT_LE_FXS16_F64: "VCVT.LE.FXS16.F64",
+ arm_VCVT_FXS16_F64: "VCVT.FXS16.F64",
+ arm_VCVT_ZZ_FXS16_F64: "VCVT.ZZ.FXS16.F64",
+ arm_VCVT_EQ_FXS32_F32: "VCVT.EQ.FXS32.F32",
+ arm_VCVT_NE_FXS32_F32: "VCVT.NE.FXS32.F32",
+ arm_VCVT_CS_FXS32_F32: "VCVT.CS.FXS32.F32",
+ arm_VCVT_CC_FXS32_F32: "VCVT.CC.FXS32.F32",
+ arm_VCVT_MI_FXS32_F32: "VCVT.MI.FXS32.F32",
+ arm_VCVT_PL_FXS32_F32: "VCVT.PL.FXS32.F32",
+ arm_VCVT_VS_FXS32_F32: "VCVT.VS.FXS32.F32",
+ arm_VCVT_VC_FXS32_F32: "VCVT.VC.FXS32.F32",
+ arm_VCVT_HI_FXS32_F32: "VCVT.HI.FXS32.F32",
+ arm_VCVT_LS_FXS32_F32: "VCVT.LS.FXS32.F32",
+ arm_VCVT_GE_FXS32_F32: "VCVT.GE.FXS32.F32",
+ arm_VCVT_LT_FXS32_F32: "VCVT.LT.FXS32.F32",
+ arm_VCVT_GT_FXS32_F32: "VCVT.GT.FXS32.F32",
+ arm_VCVT_LE_FXS32_F32: "VCVT.LE.FXS32.F32",
+ arm_VCVT_FXS32_F32: "VCVT.FXS32.F32",
+ arm_VCVT_ZZ_FXS32_F32: "VCVT.ZZ.FXS32.F32",
+ arm_VCVT_EQ_FXS32_F64: "VCVT.EQ.FXS32.F64",
+ arm_VCVT_NE_FXS32_F64: "VCVT.NE.FXS32.F64",
+ arm_VCVT_CS_FXS32_F64: "VCVT.CS.FXS32.F64",
+ arm_VCVT_CC_FXS32_F64: "VCVT.CC.FXS32.F64",
+ arm_VCVT_MI_FXS32_F64: "VCVT.MI.FXS32.F64",
+ arm_VCVT_PL_FXS32_F64: "VCVT.PL.FXS32.F64",
+ arm_VCVT_VS_FXS32_F64: "VCVT.VS.FXS32.F64",
+ arm_VCVT_VC_FXS32_F64: "VCVT.VC.FXS32.F64",
+ arm_VCVT_HI_FXS32_F64: "VCVT.HI.FXS32.F64",
+ arm_VCVT_LS_FXS32_F64: "VCVT.LS.FXS32.F64",
+ arm_VCVT_GE_FXS32_F64: "VCVT.GE.FXS32.F64",
+ arm_VCVT_LT_FXS32_F64: "VCVT.LT.FXS32.F64",
+ arm_VCVT_GT_FXS32_F64: "VCVT.GT.FXS32.F64",
+ arm_VCVT_LE_FXS32_F64: "VCVT.LE.FXS32.F64",
+ arm_VCVT_FXS32_F64: "VCVT.FXS32.F64",
+ arm_VCVT_ZZ_FXS32_F64: "VCVT.ZZ.FXS32.F64",
+ arm_VCVT_EQ_FXU16_F32: "VCVT.EQ.FXU16.F32",
+ arm_VCVT_NE_FXU16_F32: "VCVT.NE.FXU16.F32",
+ arm_VCVT_CS_FXU16_F32: "VCVT.CS.FXU16.F32",
+ arm_VCVT_CC_FXU16_F32: "VCVT.CC.FXU16.F32",
+ arm_VCVT_MI_FXU16_F32: "VCVT.MI.FXU16.F32",
+ arm_VCVT_PL_FXU16_F32: "VCVT.PL.FXU16.F32",
+ arm_VCVT_VS_FXU16_F32: "VCVT.VS.FXU16.F32",
+ arm_VCVT_VC_FXU16_F32: "VCVT.VC.FXU16.F32",
+ arm_VCVT_HI_FXU16_F32: "VCVT.HI.FXU16.F32",
+ arm_VCVT_LS_FXU16_F32: "VCVT.LS.FXU16.F32",
+ arm_VCVT_GE_FXU16_F32: "VCVT.GE.FXU16.F32",
+ arm_VCVT_LT_FXU16_F32: "VCVT.LT.FXU16.F32",
+ arm_VCVT_GT_FXU16_F32: "VCVT.GT.FXU16.F32",
+ arm_VCVT_LE_FXU16_F32: "VCVT.LE.FXU16.F32",
+ arm_VCVT_FXU16_F32: "VCVT.FXU16.F32",
+ arm_VCVT_ZZ_FXU16_F32: "VCVT.ZZ.FXU16.F32",
+ arm_VCVT_EQ_FXU16_F64: "VCVT.EQ.FXU16.F64",
+ arm_VCVT_NE_FXU16_F64: "VCVT.NE.FXU16.F64",
+ arm_VCVT_CS_FXU16_F64: "VCVT.CS.FXU16.F64",
+ arm_VCVT_CC_FXU16_F64: "VCVT.CC.FXU16.F64",
+ arm_VCVT_MI_FXU16_F64: "VCVT.MI.FXU16.F64",
+ arm_VCVT_PL_FXU16_F64: "VCVT.PL.FXU16.F64",
+ arm_VCVT_VS_FXU16_F64: "VCVT.VS.FXU16.F64",
+ arm_VCVT_VC_FXU16_F64: "VCVT.VC.FXU16.F64",
+ arm_VCVT_HI_FXU16_F64: "VCVT.HI.FXU16.F64",
+ arm_VCVT_LS_FXU16_F64: "VCVT.LS.FXU16.F64",
+ arm_VCVT_GE_FXU16_F64: "VCVT.GE.FXU16.F64",
+ arm_VCVT_LT_FXU16_F64: "VCVT.LT.FXU16.F64",
+ arm_VCVT_GT_FXU16_F64: "VCVT.GT.FXU16.F64",
+ arm_VCVT_LE_FXU16_F64: "VCVT.LE.FXU16.F64",
+ arm_VCVT_FXU16_F64: "VCVT.FXU16.F64",
+ arm_VCVT_ZZ_FXU16_F64: "VCVT.ZZ.FXU16.F64",
+ arm_VCVT_EQ_FXU32_F32: "VCVT.EQ.FXU32.F32",
+ arm_VCVT_NE_FXU32_F32: "VCVT.NE.FXU32.F32",
+ arm_VCVT_CS_FXU32_F32: "VCVT.CS.FXU32.F32",
+ arm_VCVT_CC_FXU32_F32: "VCVT.CC.FXU32.F32",
+ arm_VCVT_MI_FXU32_F32: "VCVT.MI.FXU32.F32",
+ arm_VCVT_PL_FXU32_F32: "VCVT.PL.FXU32.F32",
+ arm_VCVT_VS_FXU32_F32: "VCVT.VS.FXU32.F32",
+ arm_VCVT_VC_FXU32_F32: "VCVT.VC.FXU32.F32",
+ arm_VCVT_HI_FXU32_F32: "VCVT.HI.FXU32.F32",
+ arm_VCVT_LS_FXU32_F32: "VCVT.LS.FXU32.F32",
+ arm_VCVT_GE_FXU32_F32: "VCVT.GE.FXU32.F32",
+ arm_VCVT_LT_FXU32_F32: "VCVT.LT.FXU32.F32",
+ arm_VCVT_GT_FXU32_F32: "VCVT.GT.FXU32.F32",
+ arm_VCVT_LE_FXU32_F32: "VCVT.LE.FXU32.F32",
+ arm_VCVT_FXU32_F32: "VCVT.FXU32.F32",
+ arm_VCVT_ZZ_FXU32_F32: "VCVT.ZZ.FXU32.F32",
+ arm_VCVT_EQ_FXU32_F64: "VCVT.EQ.FXU32.F64",
+ arm_VCVT_NE_FXU32_F64: "VCVT.NE.FXU32.F64",
+ arm_VCVT_CS_FXU32_F64: "VCVT.CS.FXU32.F64",
+ arm_VCVT_CC_FXU32_F64: "VCVT.CC.FXU32.F64",
+ arm_VCVT_MI_FXU32_F64: "VCVT.MI.FXU32.F64",
+ arm_VCVT_PL_FXU32_F64: "VCVT.PL.FXU32.F64",
+ arm_VCVT_VS_FXU32_F64: "VCVT.VS.FXU32.F64",
+ arm_VCVT_VC_FXU32_F64: "VCVT.VC.FXU32.F64",
+ arm_VCVT_HI_FXU32_F64: "VCVT.HI.FXU32.F64",
+ arm_VCVT_LS_FXU32_F64: "VCVT.LS.FXU32.F64",
+ arm_VCVT_GE_FXU32_F64: "VCVT.GE.FXU32.F64",
+ arm_VCVT_LT_FXU32_F64: "VCVT.LT.FXU32.F64",
+ arm_VCVT_GT_FXU32_F64: "VCVT.GT.FXU32.F64",
+ arm_VCVT_LE_FXU32_F64: "VCVT.LE.FXU32.F64",
+ arm_VCVT_FXU32_F64: "VCVT.FXU32.F64",
+ arm_VCVT_ZZ_FXU32_F64: "VCVT.ZZ.FXU32.F64",
+ arm_VCVTB_EQ_F32_F16: "VCVTB.EQ.F32.F16",
+ arm_VCVTB_NE_F32_F16: "VCVTB.NE.F32.F16",
+ arm_VCVTB_CS_F32_F16: "VCVTB.CS.F32.F16",
+ arm_VCVTB_CC_F32_F16: "VCVTB.CC.F32.F16",
+ arm_VCVTB_MI_F32_F16: "VCVTB.MI.F32.F16",
+ arm_VCVTB_PL_F32_F16: "VCVTB.PL.F32.F16",
+ arm_VCVTB_VS_F32_F16: "VCVTB.VS.F32.F16",
+ arm_VCVTB_VC_F32_F16: "VCVTB.VC.F32.F16",
+ arm_VCVTB_HI_F32_F16: "VCVTB.HI.F32.F16",
+ arm_VCVTB_LS_F32_F16: "VCVTB.LS.F32.F16",
+ arm_VCVTB_GE_F32_F16: "VCVTB.GE.F32.F16",
+ arm_VCVTB_LT_F32_F16: "VCVTB.LT.F32.F16",
+ arm_VCVTB_GT_F32_F16: "VCVTB.GT.F32.F16",
+ arm_VCVTB_LE_F32_F16: "VCVTB.LE.F32.F16",
+ arm_VCVTB_F32_F16: "VCVTB.F32.F16",
+ arm_VCVTB_ZZ_F32_F16: "VCVTB.ZZ.F32.F16",
+ arm_VCVTB_EQ_F16_F32: "VCVTB.EQ.F16.F32",
+ arm_VCVTB_NE_F16_F32: "VCVTB.NE.F16.F32",
+ arm_VCVTB_CS_F16_F32: "VCVTB.CS.F16.F32",
+ arm_VCVTB_CC_F16_F32: "VCVTB.CC.F16.F32",
+ arm_VCVTB_MI_F16_F32: "VCVTB.MI.F16.F32",
+ arm_VCVTB_PL_F16_F32: "VCVTB.PL.F16.F32",
+ arm_VCVTB_VS_F16_F32: "VCVTB.VS.F16.F32",
+ arm_VCVTB_VC_F16_F32: "VCVTB.VC.F16.F32",
+ arm_VCVTB_HI_F16_F32: "VCVTB.HI.F16.F32",
+ arm_VCVTB_LS_F16_F32: "VCVTB.LS.F16.F32",
+ arm_VCVTB_GE_F16_F32: "VCVTB.GE.F16.F32",
+ arm_VCVTB_LT_F16_F32: "VCVTB.LT.F16.F32",
+ arm_VCVTB_GT_F16_F32: "VCVTB.GT.F16.F32",
+ arm_VCVTB_LE_F16_F32: "VCVTB.LE.F16.F32",
+ arm_VCVTB_F16_F32: "VCVTB.F16.F32",
+ arm_VCVTB_ZZ_F16_F32: "VCVTB.ZZ.F16.F32",
+ arm_VCVTT_EQ_F32_F16: "VCVTT.EQ.F32.F16",
+ arm_VCVTT_NE_F32_F16: "VCVTT.NE.F32.F16",
+ arm_VCVTT_CS_F32_F16: "VCVTT.CS.F32.F16",
+ arm_VCVTT_CC_F32_F16: "VCVTT.CC.F32.F16",
+ arm_VCVTT_MI_F32_F16: "VCVTT.MI.F32.F16",
+ arm_VCVTT_PL_F32_F16: "VCVTT.PL.F32.F16",
+ arm_VCVTT_VS_F32_F16: "VCVTT.VS.F32.F16",
+ arm_VCVTT_VC_F32_F16: "VCVTT.VC.F32.F16",
+ arm_VCVTT_HI_F32_F16: "VCVTT.HI.F32.F16",
+ arm_VCVTT_LS_F32_F16: "VCVTT.LS.F32.F16",
+ arm_VCVTT_GE_F32_F16: "VCVTT.GE.F32.F16",
+ arm_VCVTT_LT_F32_F16: "VCVTT.LT.F32.F16",
+ arm_VCVTT_GT_F32_F16: "VCVTT.GT.F32.F16",
+ arm_VCVTT_LE_F32_F16: "VCVTT.LE.F32.F16",
+ arm_VCVTT_F32_F16: "VCVTT.F32.F16",
+ arm_VCVTT_ZZ_F32_F16: "VCVTT.ZZ.F32.F16",
+ arm_VCVTT_EQ_F16_F32: "VCVTT.EQ.F16.F32",
+ arm_VCVTT_NE_F16_F32: "VCVTT.NE.F16.F32",
+ arm_VCVTT_CS_F16_F32: "VCVTT.CS.F16.F32",
+ arm_VCVTT_CC_F16_F32: "VCVTT.CC.F16.F32",
+ arm_VCVTT_MI_F16_F32: "VCVTT.MI.F16.F32",
+ arm_VCVTT_PL_F16_F32: "VCVTT.PL.F16.F32",
+ arm_VCVTT_VS_F16_F32: "VCVTT.VS.F16.F32",
+ arm_VCVTT_VC_F16_F32: "VCVTT.VC.F16.F32",
+ arm_VCVTT_HI_F16_F32: "VCVTT.HI.F16.F32",
+ arm_VCVTT_LS_F16_F32: "VCVTT.LS.F16.F32",
+ arm_VCVTT_GE_F16_F32: "VCVTT.GE.F16.F32",
+ arm_VCVTT_LT_F16_F32: "VCVTT.LT.F16.F32",
+ arm_VCVTT_GT_F16_F32: "VCVTT.GT.F16.F32",
+ arm_VCVTT_LE_F16_F32: "VCVTT.LE.F16.F32",
+ arm_VCVTT_F16_F32: "VCVTT.F16.F32",
+ arm_VCVTT_ZZ_F16_F32: "VCVTT.ZZ.F16.F32",
+ arm_VCVTR_EQ_U32_F32: "VCVTR.EQ.U32.F32",
+ arm_VCVTR_NE_U32_F32: "VCVTR.NE.U32.F32",
+ arm_VCVTR_CS_U32_F32: "VCVTR.CS.U32.F32",
+ arm_VCVTR_CC_U32_F32: "VCVTR.CC.U32.F32",
+ arm_VCVTR_MI_U32_F32: "VCVTR.MI.U32.F32",
+ arm_VCVTR_PL_U32_F32: "VCVTR.PL.U32.F32",
+ arm_VCVTR_VS_U32_F32: "VCVTR.VS.U32.F32",
+ arm_VCVTR_VC_U32_F32: "VCVTR.VC.U32.F32",
+ arm_VCVTR_HI_U32_F32: "VCVTR.HI.U32.F32",
+ arm_VCVTR_LS_U32_F32: "VCVTR.LS.U32.F32",
+ arm_VCVTR_GE_U32_F32: "VCVTR.GE.U32.F32",
+ arm_VCVTR_LT_U32_F32: "VCVTR.LT.U32.F32",
+ arm_VCVTR_GT_U32_F32: "VCVTR.GT.U32.F32",
+ arm_VCVTR_LE_U32_F32: "VCVTR.LE.U32.F32",
+ arm_VCVTR_U32_F32: "VCVTR.U32.F32",
+ arm_VCVTR_ZZ_U32_F32: "VCVTR.ZZ.U32.F32",
+ arm_VCVTR_EQ_U32_F64: "VCVTR.EQ.U32.F64",
+ arm_VCVTR_NE_U32_F64: "VCVTR.NE.U32.F64",
+ arm_VCVTR_CS_U32_F64: "VCVTR.CS.U32.F64",
+ arm_VCVTR_CC_U32_F64: "VCVTR.CC.U32.F64",
+ arm_VCVTR_MI_U32_F64: "VCVTR.MI.U32.F64",
+ arm_VCVTR_PL_U32_F64: "VCVTR.PL.U32.F64",
+ arm_VCVTR_VS_U32_F64: "VCVTR.VS.U32.F64",
+ arm_VCVTR_VC_U32_F64: "VCVTR.VC.U32.F64",
+ arm_VCVTR_HI_U32_F64: "VCVTR.HI.U32.F64",
+ arm_VCVTR_LS_U32_F64: "VCVTR.LS.U32.F64",
+ arm_VCVTR_GE_U32_F64: "VCVTR.GE.U32.F64",
+ arm_VCVTR_LT_U32_F64: "VCVTR.LT.U32.F64",
+ arm_VCVTR_GT_U32_F64: "VCVTR.GT.U32.F64",
+ arm_VCVTR_LE_U32_F64: "VCVTR.LE.U32.F64",
+ arm_VCVTR_U32_F64: "VCVTR.U32.F64",
+ arm_VCVTR_ZZ_U32_F64: "VCVTR.ZZ.U32.F64",
+ arm_VCVTR_EQ_S32_F32: "VCVTR.EQ.S32.F32",
+ arm_VCVTR_NE_S32_F32: "VCVTR.NE.S32.F32",
+ arm_VCVTR_CS_S32_F32: "VCVTR.CS.S32.F32",
+ arm_VCVTR_CC_S32_F32: "VCVTR.CC.S32.F32",
+ arm_VCVTR_MI_S32_F32: "VCVTR.MI.S32.F32",
+ arm_VCVTR_PL_S32_F32: "VCVTR.PL.S32.F32",
+ arm_VCVTR_VS_S32_F32: "VCVTR.VS.S32.F32",
+ arm_VCVTR_VC_S32_F32: "VCVTR.VC.S32.F32",
+ arm_VCVTR_HI_S32_F32: "VCVTR.HI.S32.F32",
+ arm_VCVTR_LS_S32_F32: "VCVTR.LS.S32.F32",
+ arm_VCVTR_GE_S32_F32: "VCVTR.GE.S32.F32",
+ arm_VCVTR_LT_S32_F32: "VCVTR.LT.S32.F32",
+ arm_VCVTR_GT_S32_F32: "VCVTR.GT.S32.F32",
+ arm_VCVTR_LE_S32_F32: "VCVTR.LE.S32.F32",
+ arm_VCVTR_S32_F32: "VCVTR.S32.F32",
+ arm_VCVTR_ZZ_S32_F32: "VCVTR.ZZ.S32.F32",
+ arm_VCVTR_EQ_S32_F64: "VCVTR.EQ.S32.F64",
+ arm_VCVTR_NE_S32_F64: "VCVTR.NE.S32.F64",
+ arm_VCVTR_CS_S32_F64: "VCVTR.CS.S32.F64",
+ arm_VCVTR_CC_S32_F64: "VCVTR.CC.S32.F64",
+ arm_VCVTR_MI_S32_F64: "VCVTR.MI.S32.F64",
+ arm_VCVTR_PL_S32_F64: "VCVTR.PL.S32.F64",
+ arm_VCVTR_VS_S32_F64: "VCVTR.VS.S32.F64",
+ arm_VCVTR_VC_S32_F64: "VCVTR.VC.S32.F64",
+ arm_VCVTR_HI_S32_F64: "VCVTR.HI.S32.F64",
+ arm_VCVTR_LS_S32_F64: "VCVTR.LS.S32.F64",
+ arm_VCVTR_GE_S32_F64: "VCVTR.GE.S32.F64",
+ arm_VCVTR_LT_S32_F64: "VCVTR.LT.S32.F64",
+ arm_VCVTR_GT_S32_F64: "VCVTR.GT.S32.F64",
+ arm_VCVTR_LE_S32_F64: "VCVTR.LE.S32.F64",
+ arm_VCVTR_S32_F64: "VCVTR.S32.F64",
+ arm_VCVTR_ZZ_S32_F64: "VCVTR.ZZ.S32.F64",
+ arm_VCVT_EQ_U32_F32: "VCVT.EQ.U32.F32",
+ arm_VCVT_NE_U32_F32: "VCVT.NE.U32.F32",
+ arm_VCVT_CS_U32_F32: "VCVT.CS.U32.F32",
+ arm_VCVT_CC_U32_F32: "VCVT.CC.U32.F32",
+ arm_VCVT_MI_U32_F32: "VCVT.MI.U32.F32",
+ arm_VCVT_PL_U32_F32: "VCVT.PL.U32.F32",
+ arm_VCVT_VS_U32_F32: "VCVT.VS.U32.F32",
+ arm_VCVT_VC_U32_F32: "VCVT.VC.U32.F32",
+ arm_VCVT_HI_U32_F32: "VCVT.HI.U32.F32",
+ arm_VCVT_LS_U32_F32: "VCVT.LS.U32.F32",
+ arm_VCVT_GE_U32_F32: "VCVT.GE.U32.F32",
+ arm_VCVT_LT_U32_F32: "VCVT.LT.U32.F32",
+ arm_VCVT_GT_U32_F32: "VCVT.GT.U32.F32",
+ arm_VCVT_LE_U32_F32: "VCVT.LE.U32.F32",
+ arm_VCVT_U32_F32: "VCVT.U32.F32",
+ arm_VCVT_ZZ_U32_F32: "VCVT.ZZ.U32.F32",
+ arm_VCVT_EQ_U32_F64: "VCVT.EQ.U32.F64",
+ arm_VCVT_NE_U32_F64: "VCVT.NE.U32.F64",
+ arm_VCVT_CS_U32_F64: "VCVT.CS.U32.F64",
+ arm_VCVT_CC_U32_F64: "VCVT.CC.U32.F64",
+ arm_VCVT_MI_U32_F64: "VCVT.MI.U32.F64",
+ arm_VCVT_PL_U32_F64: "VCVT.PL.U32.F64",
+ arm_VCVT_VS_U32_F64: "VCVT.VS.U32.F64",
+ arm_VCVT_VC_U32_F64: "VCVT.VC.U32.F64",
+ arm_VCVT_HI_U32_F64: "VCVT.HI.U32.F64",
+ arm_VCVT_LS_U32_F64: "VCVT.LS.U32.F64",
+ arm_VCVT_GE_U32_F64: "VCVT.GE.U32.F64",
+ arm_VCVT_LT_U32_F64: "VCVT.LT.U32.F64",
+ arm_VCVT_GT_U32_F64: "VCVT.GT.U32.F64",
+ arm_VCVT_LE_U32_F64: "VCVT.LE.U32.F64",
+ arm_VCVT_U32_F64: "VCVT.U32.F64",
+ arm_VCVT_ZZ_U32_F64: "VCVT.ZZ.U32.F64",
+ arm_VCVT_EQ_S32_F32: "VCVT.EQ.S32.F32",
+ arm_VCVT_NE_S32_F32: "VCVT.NE.S32.F32",
+ arm_VCVT_CS_S32_F32: "VCVT.CS.S32.F32",
+ arm_VCVT_CC_S32_F32: "VCVT.CC.S32.F32",
+ arm_VCVT_MI_S32_F32: "VCVT.MI.S32.F32",
+ arm_VCVT_PL_S32_F32: "VCVT.PL.S32.F32",
+ arm_VCVT_VS_S32_F32: "VCVT.VS.S32.F32",
+ arm_VCVT_VC_S32_F32: "VCVT.VC.S32.F32",
+ arm_VCVT_HI_S32_F32: "VCVT.HI.S32.F32",
+ arm_VCVT_LS_S32_F32: "VCVT.LS.S32.F32",
+ arm_VCVT_GE_S32_F32: "VCVT.GE.S32.F32",
+ arm_VCVT_LT_S32_F32: "VCVT.LT.S32.F32",
+ arm_VCVT_GT_S32_F32: "VCVT.GT.S32.F32",
+ arm_VCVT_LE_S32_F32: "VCVT.LE.S32.F32",
+ arm_VCVT_S32_F32: "VCVT.S32.F32",
+ arm_VCVT_ZZ_S32_F32: "VCVT.ZZ.S32.F32",
+ arm_VCVT_EQ_S32_F64: "VCVT.EQ.S32.F64",
+ arm_VCVT_NE_S32_F64: "VCVT.NE.S32.F64",
+ arm_VCVT_CS_S32_F64: "VCVT.CS.S32.F64",
+ arm_VCVT_CC_S32_F64: "VCVT.CC.S32.F64",
+ arm_VCVT_MI_S32_F64: "VCVT.MI.S32.F64",
+ arm_VCVT_PL_S32_F64: "VCVT.PL.S32.F64",
+ arm_VCVT_VS_S32_F64: "VCVT.VS.S32.F64",
+ arm_VCVT_VC_S32_F64: "VCVT.VC.S32.F64",
+ arm_VCVT_HI_S32_F64: "VCVT.HI.S32.F64",
+ arm_VCVT_LS_S32_F64: "VCVT.LS.S32.F64",
+ arm_VCVT_GE_S32_F64: "VCVT.GE.S32.F64",
+ arm_VCVT_LT_S32_F64: "VCVT.LT.S32.F64",
+ arm_VCVT_GT_S32_F64: "VCVT.GT.S32.F64",
+ arm_VCVT_LE_S32_F64: "VCVT.LE.S32.F64",
+ arm_VCVT_S32_F64: "VCVT.S32.F64",
+ arm_VCVT_ZZ_S32_F64: "VCVT.ZZ.S32.F64",
+ arm_VDIV_EQ_F32: "VDIV.EQ.F32",
+ arm_VDIV_NE_F32: "VDIV.NE.F32",
+ arm_VDIV_CS_F32: "VDIV.CS.F32",
+ arm_VDIV_CC_F32: "VDIV.CC.F32",
+ arm_VDIV_MI_F32: "VDIV.MI.F32",
+ arm_VDIV_PL_F32: "VDIV.PL.F32",
+ arm_VDIV_VS_F32: "VDIV.VS.F32",
+ arm_VDIV_VC_F32: "VDIV.VC.F32",
+ arm_VDIV_HI_F32: "VDIV.HI.F32",
+ arm_VDIV_LS_F32: "VDIV.LS.F32",
+ arm_VDIV_GE_F32: "VDIV.GE.F32",
+ arm_VDIV_LT_F32: "VDIV.LT.F32",
+ arm_VDIV_GT_F32: "VDIV.GT.F32",
+ arm_VDIV_LE_F32: "VDIV.LE.F32",
+ arm_VDIV_F32: "VDIV.F32",
+ arm_VDIV_ZZ_F32: "VDIV.ZZ.F32",
+ arm_VDIV_EQ_F64: "VDIV.EQ.F64",
+ arm_VDIV_NE_F64: "VDIV.NE.F64",
+ arm_VDIV_CS_F64: "VDIV.CS.F64",
+ arm_VDIV_CC_F64: "VDIV.CC.F64",
+ arm_VDIV_MI_F64: "VDIV.MI.F64",
+ arm_VDIV_PL_F64: "VDIV.PL.F64",
+ arm_VDIV_VS_F64: "VDIV.VS.F64",
+ arm_VDIV_VC_F64: "VDIV.VC.F64",
+ arm_VDIV_HI_F64: "VDIV.HI.F64",
+ arm_VDIV_LS_F64: "VDIV.LS.F64",
+ arm_VDIV_GE_F64: "VDIV.GE.F64",
+ arm_VDIV_LT_F64: "VDIV.LT.F64",
+ arm_VDIV_GT_F64: "VDIV.GT.F64",
+ arm_VDIV_LE_F64: "VDIV.LE.F64",
+ arm_VDIV_F64: "VDIV.F64",
+ arm_VDIV_ZZ_F64: "VDIV.ZZ.F64",
+ arm_VLDR_EQ: "VLDR.EQ",
+ arm_VLDR_NE: "VLDR.NE",
+ arm_VLDR_CS: "VLDR.CS",
+ arm_VLDR_CC: "VLDR.CC",
+ arm_VLDR_MI: "VLDR.MI",
+ arm_VLDR_PL: "VLDR.PL",
+ arm_VLDR_VS: "VLDR.VS",
+ arm_VLDR_VC: "VLDR.VC",
+ arm_VLDR_HI: "VLDR.HI",
+ arm_VLDR_LS: "VLDR.LS",
+ arm_VLDR_GE: "VLDR.GE",
+ arm_VLDR_LT: "VLDR.LT",
+ arm_VLDR_GT: "VLDR.GT",
+ arm_VLDR_LE: "VLDR.LE",
+ arm_VLDR: "VLDR",
+ arm_VLDR_ZZ: "VLDR.ZZ",
+ arm_VMLA_EQ_F32: "VMLA.EQ.F32",
+ arm_VMLA_NE_F32: "VMLA.NE.F32",
+ arm_VMLA_CS_F32: "VMLA.CS.F32",
+ arm_VMLA_CC_F32: "VMLA.CC.F32",
+ arm_VMLA_MI_F32: "VMLA.MI.F32",
+ arm_VMLA_PL_F32: "VMLA.PL.F32",
+ arm_VMLA_VS_F32: "VMLA.VS.F32",
+ arm_VMLA_VC_F32: "VMLA.VC.F32",
+ arm_VMLA_HI_F32: "VMLA.HI.F32",
+ arm_VMLA_LS_F32: "VMLA.LS.F32",
+ arm_VMLA_GE_F32: "VMLA.GE.F32",
+ arm_VMLA_LT_F32: "VMLA.LT.F32",
+ arm_VMLA_GT_F32: "VMLA.GT.F32",
+ arm_VMLA_LE_F32: "VMLA.LE.F32",
+ arm_VMLA_F32: "VMLA.F32",
+ arm_VMLA_ZZ_F32: "VMLA.ZZ.F32",
+ arm_VMLA_EQ_F64: "VMLA.EQ.F64",
+ arm_VMLA_NE_F64: "VMLA.NE.F64",
+ arm_VMLA_CS_F64: "VMLA.CS.F64",
+ arm_VMLA_CC_F64: "VMLA.CC.F64",
+ arm_VMLA_MI_F64: "VMLA.MI.F64",
+ arm_VMLA_PL_F64: "VMLA.PL.F64",
+ arm_VMLA_VS_F64: "VMLA.VS.F64",
+ arm_VMLA_VC_F64: "VMLA.VC.F64",
+ arm_VMLA_HI_F64: "VMLA.HI.F64",
+ arm_VMLA_LS_F64: "VMLA.LS.F64",
+ arm_VMLA_GE_F64: "VMLA.GE.F64",
+ arm_VMLA_LT_F64: "VMLA.LT.F64",
+ arm_VMLA_GT_F64: "VMLA.GT.F64",
+ arm_VMLA_LE_F64: "VMLA.LE.F64",
+ arm_VMLA_F64: "VMLA.F64",
+ arm_VMLA_ZZ_F64: "VMLA.ZZ.F64",
+ arm_VMLS_EQ_F32: "VMLS.EQ.F32",
+ arm_VMLS_NE_F32: "VMLS.NE.F32",
+ arm_VMLS_CS_F32: "VMLS.CS.F32",
+ arm_VMLS_CC_F32: "VMLS.CC.F32",
+ arm_VMLS_MI_F32: "VMLS.MI.F32",
+ arm_VMLS_PL_F32: "VMLS.PL.F32",
+ arm_VMLS_VS_F32: "VMLS.VS.F32",
+ arm_VMLS_VC_F32: "VMLS.VC.F32",
+ arm_VMLS_HI_F32: "VMLS.HI.F32",
+ arm_VMLS_LS_F32: "VMLS.LS.F32",
+ arm_VMLS_GE_F32: "VMLS.GE.F32",
+ arm_VMLS_LT_F32: "VMLS.LT.F32",
+ arm_VMLS_GT_F32: "VMLS.GT.F32",
+ arm_VMLS_LE_F32: "VMLS.LE.F32",
+ arm_VMLS_F32: "VMLS.F32",
+ arm_VMLS_ZZ_F32: "VMLS.ZZ.F32",
+ arm_VMLS_EQ_F64: "VMLS.EQ.F64",
+ arm_VMLS_NE_F64: "VMLS.NE.F64",
+ arm_VMLS_CS_F64: "VMLS.CS.F64",
+ arm_VMLS_CC_F64: "VMLS.CC.F64",
+ arm_VMLS_MI_F64: "VMLS.MI.F64",
+ arm_VMLS_PL_F64: "VMLS.PL.F64",
+ arm_VMLS_VS_F64: "VMLS.VS.F64",
+ arm_VMLS_VC_F64: "VMLS.VC.F64",
+ arm_VMLS_HI_F64: "VMLS.HI.F64",
+ arm_VMLS_LS_F64: "VMLS.LS.F64",
+ arm_VMLS_GE_F64: "VMLS.GE.F64",
+ arm_VMLS_LT_F64: "VMLS.LT.F64",
+ arm_VMLS_GT_F64: "VMLS.GT.F64",
+ arm_VMLS_LE_F64: "VMLS.LE.F64",
+ arm_VMLS_F64: "VMLS.F64",
+ arm_VMLS_ZZ_F64: "VMLS.ZZ.F64",
+ arm_VMOV_EQ: "VMOV.EQ",
+ arm_VMOV_NE: "VMOV.NE",
+ arm_VMOV_CS: "VMOV.CS",
+ arm_VMOV_CC: "VMOV.CC",
+ arm_VMOV_MI: "VMOV.MI",
+ arm_VMOV_PL: "VMOV.PL",
+ arm_VMOV_VS: "VMOV.VS",
+ arm_VMOV_VC: "VMOV.VC",
+ arm_VMOV_HI: "VMOV.HI",
+ arm_VMOV_LS: "VMOV.LS",
+ arm_VMOV_GE: "VMOV.GE",
+ arm_VMOV_LT: "VMOV.LT",
+ arm_VMOV_GT: "VMOV.GT",
+ arm_VMOV_LE: "VMOV.LE",
+ arm_VMOV: "VMOV",
+ arm_VMOV_ZZ: "VMOV.ZZ",
+ arm_VMOV_EQ_32: "VMOV.EQ.32",
+ arm_VMOV_NE_32: "VMOV.NE.32",
+ arm_VMOV_CS_32: "VMOV.CS.32",
+ arm_VMOV_CC_32: "VMOV.CC.32",
+ arm_VMOV_MI_32: "VMOV.MI.32",
+ arm_VMOV_PL_32: "VMOV.PL.32",
+ arm_VMOV_VS_32: "VMOV.VS.32",
+ arm_VMOV_VC_32: "VMOV.VC.32",
+ arm_VMOV_HI_32: "VMOV.HI.32",
+ arm_VMOV_LS_32: "VMOV.LS.32",
+ arm_VMOV_GE_32: "VMOV.GE.32",
+ arm_VMOV_LT_32: "VMOV.LT.32",
+ arm_VMOV_GT_32: "VMOV.GT.32",
+ arm_VMOV_LE_32: "VMOV.LE.32",
+ arm_VMOV_32: "VMOV.32",
+ arm_VMOV_ZZ_32: "VMOV.ZZ.32",
+ arm_VMOV_EQ_F32: "VMOV.EQ.F32",
+ arm_VMOV_NE_F32: "VMOV.NE.F32",
+ arm_VMOV_CS_F32: "VMOV.CS.F32",
+ arm_VMOV_CC_F32: "VMOV.CC.F32",
+ arm_VMOV_MI_F32: "VMOV.MI.F32",
+ arm_VMOV_PL_F32: "VMOV.PL.F32",
+ arm_VMOV_VS_F32: "VMOV.VS.F32",
+ arm_VMOV_VC_F32: "VMOV.VC.F32",
+ arm_VMOV_HI_F32: "VMOV.HI.F32",
+ arm_VMOV_LS_F32: "VMOV.LS.F32",
+ arm_VMOV_GE_F32: "VMOV.GE.F32",
+ arm_VMOV_LT_F32: "VMOV.LT.F32",
+ arm_VMOV_GT_F32: "VMOV.GT.F32",
+ arm_VMOV_LE_F32: "VMOV.LE.F32",
+ arm_VMOV_F32: "VMOV.F32",
+ arm_VMOV_ZZ_F32: "VMOV.ZZ.F32",
+ arm_VMOV_EQ_F64: "VMOV.EQ.F64",
+ arm_VMOV_NE_F64: "VMOV.NE.F64",
+ arm_VMOV_CS_F64: "VMOV.CS.F64",
+ arm_VMOV_CC_F64: "VMOV.CC.F64",
+ arm_VMOV_MI_F64: "VMOV.MI.F64",
+ arm_VMOV_PL_F64: "VMOV.PL.F64",
+ arm_VMOV_VS_F64: "VMOV.VS.F64",
+ arm_VMOV_VC_F64: "VMOV.VC.F64",
+ arm_VMOV_HI_F64: "VMOV.HI.F64",
+ arm_VMOV_LS_F64: "VMOV.LS.F64",
+ arm_VMOV_GE_F64: "VMOV.GE.F64",
+ arm_VMOV_LT_F64: "VMOV.LT.F64",
+ arm_VMOV_GT_F64: "VMOV.GT.F64",
+ arm_VMOV_LE_F64: "VMOV.LE.F64",
+ arm_VMOV_F64: "VMOV.F64",
+ arm_VMOV_ZZ_F64: "VMOV.ZZ.F64",
+ arm_VMRS_EQ: "VMRS.EQ",
+ arm_VMRS_NE: "VMRS.NE",
+ arm_VMRS_CS: "VMRS.CS",
+ arm_VMRS_CC: "VMRS.CC",
+ arm_VMRS_MI: "VMRS.MI",
+ arm_VMRS_PL: "VMRS.PL",
+ arm_VMRS_VS: "VMRS.VS",
+ arm_VMRS_VC: "VMRS.VC",
+ arm_VMRS_HI: "VMRS.HI",
+ arm_VMRS_LS: "VMRS.LS",
+ arm_VMRS_GE: "VMRS.GE",
+ arm_VMRS_LT: "VMRS.LT",
+ arm_VMRS_GT: "VMRS.GT",
+ arm_VMRS_LE: "VMRS.LE",
+ arm_VMRS: "VMRS",
+ arm_VMRS_ZZ: "VMRS.ZZ",
+ arm_VMSR_EQ: "VMSR.EQ",
+ arm_VMSR_NE: "VMSR.NE",
+ arm_VMSR_CS: "VMSR.CS",
+ arm_VMSR_CC: "VMSR.CC",
+ arm_VMSR_MI: "VMSR.MI",
+ arm_VMSR_PL: "VMSR.PL",
+ arm_VMSR_VS: "VMSR.VS",
+ arm_VMSR_VC: "VMSR.VC",
+ arm_VMSR_HI: "VMSR.HI",
+ arm_VMSR_LS: "VMSR.LS",
+ arm_VMSR_GE: "VMSR.GE",
+ arm_VMSR_LT: "VMSR.LT",
+ arm_VMSR_GT: "VMSR.GT",
+ arm_VMSR_LE: "VMSR.LE",
+ arm_VMSR: "VMSR",
+ arm_VMSR_ZZ: "VMSR.ZZ",
+ arm_VMUL_EQ_F32: "VMUL.EQ.F32",
+ arm_VMUL_NE_F32: "VMUL.NE.F32",
+ arm_VMUL_CS_F32: "VMUL.CS.F32",
+ arm_VMUL_CC_F32: "VMUL.CC.F32",
+ arm_VMUL_MI_F32: "VMUL.MI.F32",
+ arm_VMUL_PL_F32: "VMUL.PL.F32",
+ arm_VMUL_VS_F32: "VMUL.VS.F32",
+ arm_VMUL_VC_F32: "VMUL.VC.F32",
+ arm_VMUL_HI_F32: "VMUL.HI.F32",
+ arm_VMUL_LS_F32: "VMUL.LS.F32",
+ arm_VMUL_GE_F32: "VMUL.GE.F32",
+ arm_VMUL_LT_F32: "VMUL.LT.F32",
+ arm_VMUL_GT_F32: "VMUL.GT.F32",
+ arm_VMUL_LE_F32: "VMUL.LE.F32",
+ arm_VMUL_F32: "VMUL.F32",
+ arm_VMUL_ZZ_F32: "VMUL.ZZ.F32",
+ arm_VMUL_EQ_F64: "VMUL.EQ.F64",
+ arm_VMUL_NE_F64: "VMUL.NE.F64",
+ arm_VMUL_CS_F64: "VMUL.CS.F64",
+ arm_VMUL_CC_F64: "VMUL.CC.F64",
+ arm_VMUL_MI_F64: "VMUL.MI.F64",
+ arm_VMUL_PL_F64: "VMUL.PL.F64",
+ arm_VMUL_VS_F64: "VMUL.VS.F64",
+ arm_VMUL_VC_F64: "VMUL.VC.F64",
+ arm_VMUL_HI_F64: "VMUL.HI.F64",
+ arm_VMUL_LS_F64: "VMUL.LS.F64",
+ arm_VMUL_GE_F64: "VMUL.GE.F64",
+ arm_VMUL_LT_F64: "VMUL.LT.F64",
+ arm_VMUL_GT_F64: "VMUL.GT.F64",
+ arm_VMUL_LE_F64: "VMUL.LE.F64",
+ arm_VMUL_F64: "VMUL.F64",
+ arm_VMUL_ZZ_F64: "VMUL.ZZ.F64",
+ arm_VNEG_EQ_F32: "VNEG.EQ.F32",
+ arm_VNEG_NE_F32: "VNEG.NE.F32",
+ arm_VNEG_CS_F32: "VNEG.CS.F32",
+ arm_VNEG_CC_F32: "VNEG.CC.F32",
+ arm_VNEG_MI_F32: "VNEG.MI.F32",
+ arm_VNEG_PL_F32: "VNEG.PL.F32",
+ arm_VNEG_VS_F32: "VNEG.VS.F32",
+ arm_VNEG_VC_F32: "VNEG.VC.F32",
+ arm_VNEG_HI_F32: "VNEG.HI.F32",
+ arm_VNEG_LS_F32: "VNEG.LS.F32",
+ arm_VNEG_GE_F32: "VNEG.GE.F32",
+ arm_VNEG_LT_F32: "VNEG.LT.F32",
+ arm_VNEG_GT_F32: "VNEG.GT.F32",
+ arm_VNEG_LE_F32: "VNEG.LE.F32",
+ arm_VNEG_F32: "VNEG.F32",
+ arm_VNEG_ZZ_F32: "VNEG.ZZ.F32",
+ arm_VNEG_EQ_F64: "VNEG.EQ.F64",
+ arm_VNEG_NE_F64: "VNEG.NE.F64",
+ arm_VNEG_CS_F64: "VNEG.CS.F64",
+ arm_VNEG_CC_F64: "VNEG.CC.F64",
+ arm_VNEG_MI_F64: "VNEG.MI.F64",
+ arm_VNEG_PL_F64: "VNEG.PL.F64",
+ arm_VNEG_VS_F64: "VNEG.VS.F64",
+ arm_VNEG_VC_F64: "VNEG.VC.F64",
+ arm_VNEG_HI_F64: "VNEG.HI.F64",
+ arm_VNEG_LS_F64: "VNEG.LS.F64",
+ arm_VNEG_GE_F64: "VNEG.GE.F64",
+ arm_VNEG_LT_F64: "VNEG.LT.F64",
+ arm_VNEG_GT_F64: "VNEG.GT.F64",
+ arm_VNEG_LE_F64: "VNEG.LE.F64",
+ arm_VNEG_F64: "VNEG.F64",
+ arm_VNEG_ZZ_F64: "VNEG.ZZ.F64",
+ arm_VNMLS_EQ_F32: "VNMLS.EQ.F32",
+ arm_VNMLS_NE_F32: "VNMLS.NE.F32",
+ arm_VNMLS_CS_F32: "VNMLS.CS.F32",
+ arm_VNMLS_CC_F32: "VNMLS.CC.F32",
+ arm_VNMLS_MI_F32: "VNMLS.MI.F32",
+ arm_VNMLS_PL_F32: "VNMLS.PL.F32",
+ arm_VNMLS_VS_F32: "VNMLS.VS.F32",
+ arm_VNMLS_VC_F32: "VNMLS.VC.F32",
+ arm_VNMLS_HI_F32: "VNMLS.HI.F32",
+ arm_VNMLS_LS_F32: "VNMLS.LS.F32",
+ arm_VNMLS_GE_F32: "VNMLS.GE.F32",
+ arm_VNMLS_LT_F32: "VNMLS.LT.F32",
+ arm_VNMLS_GT_F32: "VNMLS.GT.F32",
+ arm_VNMLS_LE_F32: "VNMLS.LE.F32",
+ arm_VNMLS_F32: "VNMLS.F32",
+ arm_VNMLS_ZZ_F32: "VNMLS.ZZ.F32",
+ arm_VNMLS_EQ_F64: "VNMLS.EQ.F64",
+ arm_VNMLS_NE_F64: "VNMLS.NE.F64",
+ arm_VNMLS_CS_F64: "VNMLS.CS.F64",
+ arm_VNMLS_CC_F64: "VNMLS.CC.F64",
+ arm_VNMLS_MI_F64: "VNMLS.MI.F64",
+ arm_VNMLS_PL_F64: "VNMLS.PL.F64",
+ arm_VNMLS_VS_F64: "VNMLS.VS.F64",
+ arm_VNMLS_VC_F64: "VNMLS.VC.F64",
+ arm_VNMLS_HI_F64: "VNMLS.HI.F64",
+ arm_VNMLS_LS_F64: "VNMLS.LS.F64",
+ arm_VNMLS_GE_F64: "VNMLS.GE.F64",
+ arm_VNMLS_LT_F64: "VNMLS.LT.F64",
+ arm_VNMLS_GT_F64: "VNMLS.GT.F64",
+ arm_VNMLS_LE_F64: "VNMLS.LE.F64",
+ arm_VNMLS_F64: "VNMLS.F64",
+ arm_VNMLS_ZZ_F64: "VNMLS.ZZ.F64",
+ arm_VNMLA_EQ_F32: "VNMLA.EQ.F32",
+ arm_VNMLA_NE_F32: "VNMLA.NE.F32",
+ arm_VNMLA_CS_F32: "VNMLA.CS.F32",
+ arm_VNMLA_CC_F32: "VNMLA.CC.F32",
+ arm_VNMLA_MI_F32: "VNMLA.MI.F32",
+ arm_VNMLA_PL_F32: "VNMLA.PL.F32",
+ arm_VNMLA_VS_F32: "VNMLA.VS.F32",
+ arm_VNMLA_VC_F32: "VNMLA.VC.F32",
+ arm_VNMLA_HI_F32: "VNMLA.HI.F32",
+ arm_VNMLA_LS_F32: "VNMLA.LS.F32",
+ arm_VNMLA_GE_F32: "VNMLA.GE.F32",
+ arm_VNMLA_LT_F32: "VNMLA.LT.F32",
+ arm_VNMLA_GT_F32: "VNMLA.GT.F32",
+ arm_VNMLA_LE_F32: "VNMLA.LE.F32",
+ arm_VNMLA_F32: "VNMLA.F32",
+ arm_VNMLA_ZZ_F32: "VNMLA.ZZ.F32",
+ arm_VNMLA_EQ_F64: "VNMLA.EQ.F64",
+ arm_VNMLA_NE_F64: "VNMLA.NE.F64",
+ arm_VNMLA_CS_F64: "VNMLA.CS.F64",
+ arm_VNMLA_CC_F64: "VNMLA.CC.F64",
+ arm_VNMLA_MI_F64: "VNMLA.MI.F64",
+ arm_VNMLA_PL_F64: "VNMLA.PL.F64",
+ arm_VNMLA_VS_F64: "VNMLA.VS.F64",
+ arm_VNMLA_VC_F64: "VNMLA.VC.F64",
+ arm_VNMLA_HI_F64: "VNMLA.HI.F64",
+ arm_VNMLA_LS_F64: "VNMLA.LS.F64",
+ arm_VNMLA_GE_F64: "VNMLA.GE.F64",
+ arm_VNMLA_LT_F64: "VNMLA.LT.F64",
+ arm_VNMLA_GT_F64: "VNMLA.GT.F64",
+ arm_VNMLA_LE_F64: "VNMLA.LE.F64",
+ arm_VNMLA_F64: "VNMLA.F64",
+ arm_VNMLA_ZZ_F64: "VNMLA.ZZ.F64",
+ arm_VNMUL_EQ_F32: "VNMUL.EQ.F32",
+ arm_VNMUL_NE_F32: "VNMUL.NE.F32",
+ arm_VNMUL_CS_F32: "VNMUL.CS.F32",
+ arm_VNMUL_CC_F32: "VNMUL.CC.F32",
+ arm_VNMUL_MI_F32: "VNMUL.MI.F32",
+ arm_VNMUL_PL_F32: "VNMUL.PL.F32",
+ arm_VNMUL_VS_F32: "VNMUL.VS.F32",
+ arm_VNMUL_VC_F32: "VNMUL.VC.F32",
+ arm_VNMUL_HI_F32: "VNMUL.HI.F32",
+ arm_VNMUL_LS_F32: "VNMUL.LS.F32",
+ arm_VNMUL_GE_F32: "VNMUL.GE.F32",
+ arm_VNMUL_LT_F32: "VNMUL.LT.F32",
+ arm_VNMUL_GT_F32: "VNMUL.GT.F32",
+ arm_VNMUL_LE_F32: "VNMUL.LE.F32",
+ arm_VNMUL_F32: "VNMUL.F32",
+ arm_VNMUL_ZZ_F32: "VNMUL.ZZ.F32",
+ arm_VNMUL_EQ_F64: "VNMUL.EQ.F64",
+ arm_VNMUL_NE_F64: "VNMUL.NE.F64",
+ arm_VNMUL_CS_F64: "VNMUL.CS.F64",
+ arm_VNMUL_CC_F64: "VNMUL.CC.F64",
+ arm_VNMUL_MI_F64: "VNMUL.MI.F64",
+ arm_VNMUL_PL_F64: "VNMUL.PL.F64",
+ arm_VNMUL_VS_F64: "VNMUL.VS.F64",
+ arm_VNMUL_VC_F64: "VNMUL.VC.F64",
+ arm_VNMUL_HI_F64: "VNMUL.HI.F64",
+ arm_VNMUL_LS_F64: "VNMUL.LS.F64",
+ arm_VNMUL_GE_F64: "VNMUL.GE.F64",
+ arm_VNMUL_LT_F64: "VNMUL.LT.F64",
+ arm_VNMUL_GT_F64: "VNMUL.GT.F64",
+ arm_VNMUL_LE_F64: "VNMUL.LE.F64",
+ arm_VNMUL_F64: "VNMUL.F64",
+ arm_VNMUL_ZZ_F64: "VNMUL.ZZ.F64",
+ arm_VSQRT_EQ_F32: "VSQRT.EQ.F32",
+ arm_VSQRT_NE_F32: "VSQRT.NE.F32",
+ arm_VSQRT_CS_F32: "VSQRT.CS.F32",
+ arm_VSQRT_CC_F32: "VSQRT.CC.F32",
+ arm_VSQRT_MI_F32: "VSQRT.MI.F32",
+ arm_VSQRT_PL_F32: "VSQRT.PL.F32",
+ arm_VSQRT_VS_F32: "VSQRT.VS.F32",
+ arm_VSQRT_VC_F32: "VSQRT.VC.F32",
+ arm_VSQRT_HI_F32: "VSQRT.HI.F32",
+ arm_VSQRT_LS_F32: "VSQRT.LS.F32",
+ arm_VSQRT_GE_F32: "VSQRT.GE.F32",
+ arm_VSQRT_LT_F32: "VSQRT.LT.F32",
+ arm_VSQRT_GT_F32: "VSQRT.GT.F32",
+ arm_VSQRT_LE_F32: "VSQRT.LE.F32",
+ arm_VSQRT_F32: "VSQRT.F32",
+ arm_VSQRT_ZZ_F32: "VSQRT.ZZ.F32",
+ arm_VSQRT_EQ_F64: "VSQRT.EQ.F64",
+ arm_VSQRT_NE_F64: "VSQRT.NE.F64",
+ arm_VSQRT_CS_F64: "VSQRT.CS.F64",
+ arm_VSQRT_CC_F64: "VSQRT.CC.F64",
+ arm_VSQRT_MI_F64: "VSQRT.MI.F64",
+ arm_VSQRT_PL_F64: "VSQRT.PL.F64",
+ arm_VSQRT_VS_F64: "VSQRT.VS.F64",
+ arm_VSQRT_VC_F64: "VSQRT.VC.F64",
+ arm_VSQRT_HI_F64: "VSQRT.HI.F64",
+ arm_VSQRT_LS_F64: "VSQRT.LS.F64",
+ arm_VSQRT_GE_F64: "VSQRT.GE.F64",
+ arm_VSQRT_LT_F64: "VSQRT.LT.F64",
+ arm_VSQRT_GT_F64: "VSQRT.GT.F64",
+ arm_VSQRT_LE_F64: "VSQRT.LE.F64",
+ arm_VSQRT_F64: "VSQRT.F64",
+ arm_VSQRT_ZZ_F64: "VSQRT.ZZ.F64",
+ arm_VSTR_EQ: "VSTR.EQ",
+ arm_VSTR_NE: "VSTR.NE",
+ arm_VSTR_CS: "VSTR.CS",
+ arm_VSTR_CC: "VSTR.CC",
+ arm_VSTR_MI: "VSTR.MI",
+ arm_VSTR_PL: "VSTR.PL",
+ arm_VSTR_VS: "VSTR.VS",
+ arm_VSTR_VC: "VSTR.VC",
+ arm_VSTR_HI: "VSTR.HI",
+ arm_VSTR_LS: "VSTR.LS",
+ arm_VSTR_GE: "VSTR.GE",
+ arm_VSTR_LT: "VSTR.LT",
+ arm_VSTR_GT: "VSTR.GT",
+ arm_VSTR_LE: "VSTR.LE",
+ arm_VSTR: "VSTR",
+ arm_VSTR_ZZ: "VSTR.ZZ",
+ arm_VSUB_EQ_F32: "VSUB.EQ.F32",
+ arm_VSUB_NE_F32: "VSUB.NE.F32",
+ arm_VSUB_CS_F32: "VSUB.CS.F32",
+ arm_VSUB_CC_F32: "VSUB.CC.F32",
+ arm_VSUB_MI_F32: "VSUB.MI.F32",
+ arm_VSUB_PL_F32: "VSUB.PL.F32",
+ arm_VSUB_VS_F32: "VSUB.VS.F32",
+ arm_VSUB_VC_F32: "VSUB.VC.F32",
+ arm_VSUB_HI_F32: "VSUB.HI.F32",
+ arm_VSUB_LS_F32: "VSUB.LS.F32",
+ arm_VSUB_GE_F32: "VSUB.GE.F32",
+ arm_VSUB_LT_F32: "VSUB.LT.F32",
+ arm_VSUB_GT_F32: "VSUB.GT.F32",
+ arm_VSUB_LE_F32: "VSUB.LE.F32",
+ arm_VSUB_F32: "VSUB.F32",
+ arm_VSUB_ZZ_F32: "VSUB.ZZ.F32",
+ arm_VSUB_EQ_F64: "VSUB.EQ.F64",
+ arm_VSUB_NE_F64: "VSUB.NE.F64",
+ arm_VSUB_CS_F64: "VSUB.CS.F64",
+ arm_VSUB_CC_F64: "VSUB.CC.F64",
+ arm_VSUB_MI_F64: "VSUB.MI.F64",
+ arm_VSUB_PL_F64: "VSUB.PL.F64",
+ arm_VSUB_VS_F64: "VSUB.VS.F64",
+ arm_VSUB_VC_F64: "VSUB.VC.F64",
+ arm_VSUB_HI_F64: "VSUB.HI.F64",
+ arm_VSUB_LS_F64: "VSUB.LS.F64",
+ arm_VSUB_GE_F64: "VSUB.GE.F64",
+ arm_VSUB_LT_F64: "VSUB.LT.F64",
+ arm_VSUB_GT_F64: "VSUB.GT.F64",
+ arm_VSUB_LE_F64: "VSUB.LE.F64",
+ arm_VSUB_F64: "VSUB.F64",
+ arm_VSUB_ZZ_F64: "VSUB.ZZ.F64",
+ arm_WFE_EQ: "WFE.EQ",
+ arm_WFE_NE: "WFE.NE",
+ arm_WFE_CS: "WFE.CS",
+ arm_WFE_CC: "WFE.CC",
+ arm_WFE_MI: "WFE.MI",
+ arm_WFE_PL: "WFE.PL",
+ arm_WFE_VS: "WFE.VS",
+ arm_WFE_VC: "WFE.VC",
+ arm_WFE_HI: "WFE.HI",
+ arm_WFE_LS: "WFE.LS",
+ arm_WFE_GE: "WFE.GE",
+ arm_WFE_LT: "WFE.LT",
+ arm_WFE_GT: "WFE.GT",
+ arm_WFE_LE: "WFE.LE",
+ arm_WFE: "WFE",
+ arm_WFE_ZZ: "WFE.ZZ",
+ arm_WFI_EQ: "WFI.EQ",
+ arm_WFI_NE: "WFI.NE",
+ arm_WFI_CS: "WFI.CS",
+ arm_WFI_CC: "WFI.CC",
+ arm_WFI_MI: "WFI.MI",
+ arm_WFI_PL: "WFI.PL",
+ arm_WFI_VS: "WFI.VS",
+ arm_WFI_VC: "WFI.VC",
+ arm_WFI_HI: "WFI.HI",
+ arm_WFI_LS: "WFI.LS",
+ arm_WFI_GE: "WFI.GE",
+ arm_WFI_LT: "WFI.LT",
+ arm_WFI_GT: "WFI.GT",
+ arm_WFI_LE: "WFI.LE",
+ arm_WFI: "WFI",
+ arm_WFI_ZZ: "WFI.ZZ",
+ arm_YIELD_EQ: "YIELD.EQ",
+ arm_YIELD_NE: "YIELD.NE",
+ arm_YIELD_CS: "YIELD.CS",
+ arm_YIELD_CC: "YIELD.CC",
+ arm_YIELD_MI: "YIELD.MI",
+ arm_YIELD_PL: "YIELD.PL",
+ arm_YIELD_VS: "YIELD.VS",
+ arm_YIELD_VC: "YIELD.VC",
+ arm_YIELD_HI: "YIELD.HI",
+ arm_YIELD_LS: "YIELD.LS",
+ arm_YIELD_GE: "YIELD.GE",
+ arm_YIELD_LT: "YIELD.LT",
+ arm_YIELD_GT: "YIELD.GT",
+ arm_YIELD_LE: "YIELD.LE",
+ arm_YIELD: "YIELD",
+ arm_YIELD_ZZ: "YIELD.ZZ",
+}
+
+var arm_instFormats = [...]arm_instFormat{
+ {0x0fe00000, 0x02a00000, 2, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // ADC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|0|1|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00a00010, 4, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ADC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00a00000, 2, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ADC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fe00000, 0x02800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // ADD{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|0|0|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00800010, 4, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ADD{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ADD{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fef0000, 0x028d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_const}}, // ADD{S}<c> <Rd>,SP,#<const> cond:4|0|0|1|0|1|0|0|S|1|1|0|1|Rd:4|imm12:12
+ {0x0fef0010, 0x008d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_R_shift_imm}}, // ADD{S}<c> <Rd>,SP,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fe00000, 0x02000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // AND{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|0|0|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00000010, 4, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // AND{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // AND{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fef0070, 0x01a00040, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_32}}, // ASR{S}<c> <Rd>,<Rm>,#<imm5_32> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|0|0|Rm:4
+ {0x0fef00f0, 0x01a00050, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}}, // ASR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|0|1|Rn:4
+ {0x0f000000, 0x0a000000, 4, arm_B_EQ, 0x1c04, arm_instArgs{arm_arg_label24}}, // B<c> <label24> cond:4|1|0|1|0|imm24:24
+ {0x0fe0007f, 0x07c0001f, 4, arm_BFC_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm5, arm_arg_lsb_width}}, // BFC<c> <Rd>,#<lsb>,#<width> cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|1|1|1|1
+ {0x0fe00070, 0x07c00010, 2, arm_BFI_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_lsb_width}}, // BFI<c> <Rd>,<Rn>,#<lsb>,#<width> cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|Rn:4
+ {0x0fe00000, 0x03c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // BIC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|1|1|1|0|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x01c00010, 4, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // BIC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x01c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // BIC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0ff000f0, 0x01200070, 4, arm_BKPT_EQ, 0x1c04, arm_instArgs{arm_arg_imm_12at8_4at0}}, // BKPT<c> #<imm12+4> cond:4|0|0|0|1|0|0|1|0|imm12:12|0|1|1|1|imm4:4
+ {0x0f000000, 0x0b000000, 4, arm_BL_EQ, 0x1c04, arm_instArgs{arm_arg_label24}}, // BL<c> <label24> cond:4|1|0|1|1|imm24:24
+ {0xfe000000, 0xfa000000, 4, arm_BLX, 0x0, arm_instArgs{arm_arg_label24H}}, // BLX <label24H> 1|1|1|1|1|0|1|H|imm24:24
+ {0x0ffffff0, 0x012fff30, 4, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BLX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x012fff30, 3, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BLX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ffffff0, 0x012fff10, 4, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x012fff10, 3, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ffffff0, 0x012fff20, 4, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BXJ<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4
+ {0x0ff000f0, 0x012fff20, 3, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BXJ<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4
+ {0xffffffff, 0xf57ff01f, 4, arm_CLREX, 0x0, arm_instArgs{}}, // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1)
+ {0xfff000f0, 0xf57ff01f, 3, arm_CLREX, 0x0, arm_instArgs{}}, // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1)
+ {0x0fff0ff0, 0x016f0f10, 4, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // CLZ<c> <Rd>,<Rm> cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x016f0f10, 3, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // CLZ<c> <Rd>,<Rm> cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff0f000, 0x03700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMN<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff00000, 0x03700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMN<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff0f090, 0x01700010, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMN<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff00090, 0x01700010, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMN<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff0f010, 0x01700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMN<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff00010, 0x01700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMN<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff0f000, 0x03500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMP<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff00000, 0x03500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMP<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff0f090, 0x01500010, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMP<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff00090, 0x01500010, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMP<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff0f010, 0x01500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMP<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff00010, 0x01500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMP<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ffffff0, 0x0320f0f0, 4, arm_DBG_EQ, 0x1c04, arm_instArgs{arm_arg_option}}, // DBG<c> #<option> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|1|1|1|1|option:4
+ {0x0fff00f0, 0x0320f0f0, 3, arm_DBG_EQ, 0x1c04, arm_instArgs{arm_arg_option}}, // DBG<c> #<option> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|1|1|1|1|option:4
+ {0xfffffff0, 0xf57ff050, 4, arm_DMB, 0x0, arm_instArgs{arm_arg_option}}, // DMB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|1|option:4
+ {0xfff000f0, 0xf57ff050, 3, arm_DMB, 0x0, arm_instArgs{arm_arg_option}}, // DMB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|1|option:4
+ {0xfffffff0, 0xf57ff040, 4, arm_DSB, 0x0, arm_instArgs{arm_arg_option}}, // DSB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|0|option:4
+ {0xfff000f0, 0xf57ff040, 3, arm_DSB, 0x0, arm_instArgs{arm_arg_option}}, // DSB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|0|option:4
+ {0x0fe00000, 0x02200000, 2, arm_EOR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // EOR{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|0|1|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00200010, 4, arm_EOR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // EOR{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00200000, 2, arm_EOR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // EOR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0xfffffff0, 0xf57ff060, 4, arm_ISB, 0x0, arm_instArgs{arm_arg_option}}, // ISB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|1|0|option:4
+ {0xfff000f0, 0xf57ff060, 3, arm_ISB, 0x0, arm_instArgs{arm_arg_option}}, // ISB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|1|0|option:4
+ {0x0fd00000, 0x08900000, 2, arm_LDM_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // LDM<c> <Rn>{!},<registers> cond:4|1|0|0|0|1|0|W|1|Rn:4|register_list:16
+ {0x0fd00000, 0x08100000, 4, arm_LDMDA_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // LDMDA<c> <Rn>{!},<registers> cond:4|1|0|0|0|0|0|W|1|Rn:4|register_list:16
+ {0x0fd00000, 0x09100000, 4, arm_LDMDB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // LDMDB<c> <Rn>{!},<registers> cond:4|1|0|0|1|0|0|W|1|Rn:4|register_list:16
+ {0x0fd00000, 0x09900000, 4, arm_LDMIB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // LDMIB<c> <Rn>{!},<registers> cond:4|1|0|0|1|1|0|W|1|Rn:4|register_list:16
+ {0x0f7f0000, 0x051f0000, 4, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}}, // LDR<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|0|(0)|1|1|1|1|1|Rt:4|imm12:12
+ {0x0e5f0000, 0x051f0000, 3, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}}, // LDR<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|0|(0)|1|1|1|1|1|Rt:4|imm12:12
+ {0x0e500010, 0x06100000, 2, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}}, // LDR<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|0|W|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0e500000, 0x04100000, 2, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}}, // LDR<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|0|W|1|Rn:4|Rt:4|imm12:12
+ {0x0f7f0000, 0x055f0000, 4, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}}, // LDRB<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|1|(0)|1|1|1|1|1|Rt:4|imm12:12
+ {0x0e5f0000, 0x055f0000, 3, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}}, // LDRB<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|1|(0)|1|1|1|1|1|Rt:4|imm12:12
+ {0x0e500010, 0x06500000, 2, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}}, // LDRB<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|1|W|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0e500000, 0x04500000, 2, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}}, // LDRB<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|1|W|1|Rn:4|Rt:4|imm12:12
+ {0x0f700000, 0x04700000, 4, arm_LDRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}}, // LDRBT<c> <Rt>,[<Rn>],#+/-<imm12> cond:4|0|1|0|0|U|1|1|1|Rn:4|Rt:4|imm12:12
+ {0x0f700010, 0x06700000, 4, arm_LDRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}}, // LDRBT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|1|1|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0e500ff0, 0x000000d0, 4, arm_LDRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}}, // LDRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|0|1|Rm:4
+ {0x0e5000f0, 0x000000d0, 3, arm_LDRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}}, // LDRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|0|1|Rm:4
+ {0x0e5000f0, 0x004000d0, 2, arm_LDRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_imm8_W}}, // LDRD<c> <Rt1>,<Rt2>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
+ {0x0ff00fff, 0x01900f9f, 4, arm_LDREX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}}, // LDREX<c> <Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff000f0, 0x01900f9f, 3, arm_LDREX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}}, // LDREX<c> <Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff00fff, 0x01d00f9f, 4, arm_LDREXB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}}, // LDREXB<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff000f0, 0x01d00f9f, 3, arm_LDREXB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}}, // LDREXB<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff00fff, 0x01b00f9f, 4, arm_LDREXD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R}}, // LDREXD<c> <Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff000f0, 0x01b00f9f, 3, arm_LDREXD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R}}, // LDREXD<c> <Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff00fff, 0x01f00f9f, 4, arm_LDREXH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}}, // LDREXH<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0ff000f0, 0x01f00f9f, 3, arm_LDREXH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}}, // LDREXH<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+ {0x0e500ff0, 0x001000b0, 2, arm_LDRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}}, // LDRH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+ {0x0e5000f0, 0x005000b0, 2, arm_LDRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}}, // LDRH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+ {0x0f7000f0, 0x007000b0, 4, arm_LDRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}}, // LDRHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+ {0x0f700ff0, 0x003000b0, 4, arm_LDRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}}, // LDRHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+ {0x0e500ff0, 0x001000d0, 2, arm_LDRSB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}}, // LDRSB<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|1|0|1|Rm:4
+ {0x0e5000f0, 0x005000d0, 2, arm_LDRSB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}}, // LDRSB<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
+ {0x0f7000f0, 0x007000d0, 4, arm_LDRSBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}}, // LDRSBT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
+ {0x0f700ff0, 0x003000d0, 4, arm_LDRSBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}}, // LDRSBT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|1|0|1|Rm:4
+ {0x0e500ff0, 0x001000f0, 2, arm_LDRSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}}, // LDRSH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|1|1|1|Rm:4
+ {0x0e5000f0, 0x005000f0, 2, arm_LDRSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}}, // LDRSH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
+ {0x0f7000f0, 0x007000f0, 4, arm_LDRSHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}}, // LDRSHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
+ {0x0f700ff0, 0x003000f0, 4, arm_LDRSHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}}, // LDRSHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|1|1|1|Rm:4
+ {0x0f700000, 0x04300000, 4, arm_LDRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}}, // LDRT<c> <Rt>, [<Rn>] {,#+/-<imm12>} cond:4|0|1|0|0|U|0|1|1|Rn:4|Rt:4|imm12:12
+ {0x0f700010, 0x06300000, 4, arm_LDRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}}, // LDRT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|0|1|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0fef0070, 0x01a00000, 2, arm_LSL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_nz}}, // LSL{S}<c> <Rd>,<Rm>,#<imm5_nz> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|0|0|0|Rm:4
+ {0x0fef00f0, 0x01a00010, 4, arm_LSL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}}, // LSL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|0|0|1|Rn:4
+ {0x0fef0070, 0x01a00020, 4, arm_LSR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_32}}, // LSR{S}<c> <Rd>,<Rm>,#<imm5_32> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|0|1|0|Rm:4
+ {0x0fef00f0, 0x01a00030, 4, arm_LSR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}}, // LSR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|0|1|1|Rn:4
+ {0x0fe000f0, 0x00200090, 4, arm_MLA_EQ, 0x14011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // MLA{S}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|0|0|0|1|S|Rd:4|Ra:4|Rm:4|1|0|0|1|Rn:4
+ {0x0ff000f0, 0x00600090, 4, arm_MLS_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // MLS<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|0|0|1|1|0|Rd:4|Ra:4|Rm:4|1|0|0|1|Rn:4
+ {0x0ff00000, 0x03400000, 4, arm_MOVT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm_4at16_12at0}}, // MOVT<c> <Rd>,#<imm12+4> cond:4|0|0|1|1|0|1|0|0|imm4:4|Rd:4|imm12:12
+ {0x0ff00000, 0x03000000, 4, arm_MOVW_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm_4at16_12at0}}, // MOVW<c> <Rd>,#<imm12+4> cond:4|0|0|1|1|0|0|0|0|imm4:4|Rd:4|imm12:12
+ {0x0fef0000, 0x03a00000, 2, arm_MOV_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_const}}, // MOV{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|0|1|S|0|0|0|0|Rd:4|imm12:12
+ {0x0fef0ff0, 0x01a00000, 2, arm_MOV_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // MOV{S}<c> <Rd>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|0|0|0|0|0|0|0|0|Rm:4
+ {0x0fff0fff, 0x010f0000, 4, arm_MRS_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_APSR}}, // MRS<c> <Rd>,APSR cond:4|0|0|0|1|0|0|0|0|(1)|(1)|(1)|(1)|Rd:4|(0)|(0)|(0)|(0)|0|0|0|0|(0)|(0)|(0)|(0)
+ {0x0ff000f0, 0x010f0000, 3, arm_MRS_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_APSR}}, // MRS<c> <Rd>,APSR cond:4|0|0|0|1|0|0|0|0|(1)|(1)|(1)|(1)|Rd:4|(0)|(0)|(0)|(0)|0|0|0|0|(0)|(0)|(0)|(0)
+ {0x0fe0f0f0, 0x00000090, 4, arm_MUL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // MUL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|0|0|0|0|S|Rd:4|(0)|(0)|(0)|(0)|Rm:4|1|0|0|1|Rn:4
+ {0x0fe000f0, 0x00000090, 3, arm_MUL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // MUL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|0|0|0|0|S|Rd:4|(0)|(0)|(0)|(0)|Rm:4|1|0|0|1|Rn:4
+ {0x0fef0000, 0x03e00000, 2, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_const}}, // MVN{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm12:12
+ {0x0fe00000, 0x03e00000, 1, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_const}}, // MVN{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm12:12
+ {0x0fef0090, 0x01e00010, 4, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_R}}, // MVN{S}<c> <Rd>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00090, 0x01e00010, 3, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_R}}, // MVN{S}<c> <Rd>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fef0010, 0x01e00000, 2, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_imm}}, // MVN{S}<c> <Rd>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fe00010, 0x01e00000, 1, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_imm}}, // MVN{S}<c> <Rd>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fffffff, 0x0320f000, 4, arm_NOP_EQ, 0x1c04, arm_instArgs{}}, // NOP<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|0
+ {0x0fff00ff, 0x0320f000, 3, arm_NOP_EQ, 0x1c04, arm_instArgs{}}, // NOP<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|0
+ {0x0fe00000, 0x03800000, 2, arm_ORR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // ORR{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|1|1|0|0|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x01800010, 4, arm_ORR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ORR{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x01800000, 2, arm_ORR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ORR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0ff00030, 0x06800010, 4, arm_PKHBT_EQ, 0x6011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // PKH<BT,TB><c> <Rd>,<Rn>,<Rm>{,LSL #<imm5>} cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|imm5:5|tb|0|1|Rm:4
+ {0xff7ff000, 0xf55ff000, 4, arm_PLD, 0x0, arm_instArgs{arm_arg_label_pm_12}}, // PLD <label+/-12> 1|1|1|1|0|1|0|1|U|(1)|0|1|1|1|1|1|(1)|(1)|(1)|(1)|imm12:12
+ {0xff3f0000, 0xf55ff000, 3, arm_PLD, 0x0, arm_instArgs{arm_arg_label_pm_12}}, // PLD <label+/-12> 1|1|1|1|0|1|0|1|U|(1)|0|1|1|1|1|1|(1)|(1)|(1)|(1)|imm12:12
+ {0xff30f000, 0xf510f000, 2, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}}, // PLD{W} [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+ {0xff300000, 0xf510f000, 1, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}}, // PLD{W} [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+ {0xff30f010, 0xf710f000, 4, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}}, // PLD{W} [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+ {0xff300010, 0xf710f000, 3, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}}, // PLD{W} [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+ {0xff70f000, 0xf450f000, 4, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}}, // PLI [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+ {0xff700000, 0xf450f000, 3, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}}, // PLI [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+ {0xff70f010, 0xf650f000, 4, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}}, // PLI [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+ {0xff700010, 0xf650f000, 3, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}}, // PLI [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+ {0x0fff0000, 0x08bd0000, 4, arm_POP_EQ, 0x1c04, arm_instArgs{arm_arg_registers2}}, // POP<c> <registers2> cond:4|1|0|0|0|1|0|1|1|1|1|0|1|register_list:16
+ {0x0fff0fff, 0x049d0004, 4, arm_POP_EQ, 0x1c04, arm_instArgs{arm_arg_registers1}}, // POP<c> <registers1> cond:4|0|1|0|0|1|0|0|1|1|1|0|1|Rt:4|0|0|0|0|0|0|0|0|0|1|0|0
+ {0x0fff0000, 0x092d0000, 4, arm_PUSH_EQ, 0x1c04, arm_instArgs{arm_arg_registers2}}, // PUSH<c> <registers2> cond:4|1|0|0|1|0|0|1|0|1|1|0|1|register_list:16
+ {0x0fff0fff, 0x052d0004, 4, arm_PUSH_EQ, 0x1c04, arm_instArgs{arm_arg_registers1}}, // PUSH<c> <registers1> cond:4|0|1|0|1|0|0|1|0|1|1|0|1|Rt:4|0|0|0|0|0|0|0|0|0|1|0|0
+ {0x0ff00ff0, 0x06200f10, 4, arm_QADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x06200f10, 3, arm_QADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06200f90, 4, arm_QADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff000f0, 0x06200f90, 3, arm_QADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff00ff0, 0x01000050, 4, arm_QADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}}, // QADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x01000050, 3, arm_QADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}}, // QADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06200f30, 4, arm_QASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06200f30, 3, arm_QASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff00ff0, 0x01400050, 4, arm_QDADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}}, // QDADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x01400050, 3, arm_QDADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}}, // QDADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x01600050, 4, arm_QDSUB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}}, // QDSUB<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|1|0|Rn:4|Rd:4|0|0|0|0|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06200f50, 4, arm_QSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x06200f50, 3, arm_QSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06200f70, 4, arm_QSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff000f0, 0x06200f70, 3, arm_QSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff00ff0, 0x06200ff0, 4, arm_QSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x06200ff0, 3, arm_QSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // QSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff00ff0, 0x01200050, 4, arm_QSUB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}}, // QSUB<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|1|0|Rn:4|Rd:4|0|0|0|0|0|1|0|1|Rm:4
+ {0x0fff0ff0, 0x06ff0f30, 4, arm_RBIT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // RBIT<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06ff0f30, 3, arm_RBIT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // RBIT<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0fff0ff0, 0x06bf0fb0, 4, arm_REV16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // REV16<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+ {0x0ff000f0, 0x06bf0fb0, 3, arm_REV16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // REV16<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+ {0x0fff0ff0, 0x06bf0f30, 4, arm_REV_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // REV<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06bf0f30, 3, arm_REV_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // REV<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0fff0ff0, 0x06ff0fb0, 4, arm_REVSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // REVSH<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+ {0x0ff000f0, 0x06ff0fb0, 3, arm_REVSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // REVSH<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+ {0x0fef0070, 0x01a00060, 2, arm_ROR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5}}, // ROR{S}<c> <Rd>,<Rm>,#<imm5> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|1|0|Rm:4
+ {0x0fef00f0, 0x01a00070, 4, arm_ROR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}}, // ROR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|1|1|Rn:4
+ {0x0fef0ff0, 0x01a00060, 4, arm_RRX_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // RRX{S}<c> <Rd>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|0|0|0|0|0|1|1|0|Rm:4
+ {0x0fe00000, 0x02600000, 2, arm_RSB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // RSB{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|1|1|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00600010, 4, arm_RSB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // RSB{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|1|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00600000, 2, arm_RSB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fe00000, 0x02e00000, 2, arm_RSC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // RSC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|1|1|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00e00010, 4, arm_RSC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // RSC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|1|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00e00000, 2, arm_RSC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // RSC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|1|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0ff00ff0, 0x06100f10, 4, arm_SADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x06100f10, 3, arm_SADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06100f90, 4, arm_SADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff000f0, 0x06100f90, 3, arm_SADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06100f30, 4, arm_SASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06100f30, 3, arm_SASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0fe00000, 0x02c00000, 2, arm_SBC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // SBC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|1|0|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00c00010, 4, arm_SBC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // SBC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00c00000, 2, arm_SBC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // SBC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fe00070, 0x07a00050, 4, arm_SBFX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_widthm1}}, // SBFX<c> <Rd>,<Rn>,#<lsb>,#<widthm1> cond:4|0|1|1|1|1|0|1|widthm1:5|Rd:4|lsb:5|1|0|1|Rn:4
+ {0x0ff00ff0, 0x06800fb0, 4, arm_SEL_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SEL<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+ {0x0ff000f0, 0x06800fb0, 3, arm_SEL_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SEL<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+ {0xfffffdff, 0xf1010000, 4, arm_SETEND, 0x0, arm_instArgs{arm_arg_endian}}, // SETEND <endian_specifier> 1|1|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|0|0|0|0|E|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)
+ {0xfffffc00, 0xf1010000, 3, arm_SETEND, 0x0, arm_instArgs{arm_arg_endian}}, // SETEND <endian_specifier> 1|1|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|0|0|0|0|E|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)
+ {0x0fffffff, 0x0320f004, 4, arm_SEV_EQ, 0x1c04, arm_instArgs{}}, // SEV<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|1|0|0
+ {0x0fff00ff, 0x0320f004, 3, arm_SEV_EQ, 0x1c04, arm_instArgs{}}, // SEV<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|1|0|0
+ {0x0ff00ff0, 0x06300f10, 4, arm_SHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x06300f10, 3, arm_SHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06300f90, 4, arm_SHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff000f0, 0x06300f90, 3, arm_SHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06300f30, 4, arm_SHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06300f30, 3, arm_SHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff00ff0, 0x06300f50, 4, arm_SHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x06300f50, 3, arm_SHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06300f70, 4, arm_SHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff000f0, 0x06300f70, 3, arm_SHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff00ff0, 0x06300ff0, 4, arm_SHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x06300ff0, 3, arm_SHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff00090, 0x01000080, 4, arm_SMLABB_EQ, 0x50106011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|1|0|0|0|0|Rd:4|Ra:4|Rm:4|1|M|N|0|Rn:4
+ {0x0ff000d0, 0x07000010, 2, arm_SMLAD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // SMLAD{X}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|0|0|0|Rd:4|Ra:4|Rm:4|0|0|M|1|Rn:4
+ {0x0ff00090, 0x01400080, 4, arm_SMLALBB_EQ, 0x50106011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMLAL<x><y><c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|1|M|N|0|Rn:4
+ {0x0ff000d0, 0x07400010, 4, arm_SMLALD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMLALD{X}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|0|0|M|1|Rn:4
+ {0x0fe000f0, 0x00e00090, 4, arm_SMLAL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMLAL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|1|1|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+ {0x0ff000b0, 0x01200080, 4, arm_SMLAWB_EQ, 0x6011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // SMLAW<y><c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|1|0|0|1|0|Rd:4|Ra:4|Rm:4|1|M|0|0|Rn:4
+ {0x0ff000d0, 0x07000050, 2, arm_SMLSD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // SMLSD{X}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|0|0|0|Rd:4|Ra:4|Rm:4|0|1|M|1|Rn:4
+ {0x0ff000d0, 0x07400050, 4, arm_SMLSLD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMLSLD{X}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|0|1|M|1|Rn:4
+ {0x0ff000d0, 0x07500010, 2, arm_SMMLA_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // SMMLA{R}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|1|0|1|Rd:4|Ra:4|Rm:4|0|0|R|1|Rn:4
+ {0x0ff000d0, 0x075000d0, 4, arm_SMMLS_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // SMMLS{R}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|1|0|1|Rd:4|Ra:4|Rm:4|1|1|R|1|Rn:4
+ {0x0ff0f0d0, 0x0750f010, 4, arm_SMMUL_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMMUL{R}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|1|Rd:4|1|1|1|1|Rm:4|0|0|R|1|Rn:4
+ {0x0ff0f0d0, 0x0700f010, 4, arm_SMUAD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMUAD{X}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|0|Rd:4|1|1|1|1|Rm:4|0|0|M|1|Rn:4
+ {0x0ff0f090, 0x01600080, 4, arm_SMULBB_EQ, 0x50106011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMUL<x><y><c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|0|1|1|0|Rd:4|0|0|0|0|Rm:4|1|M|N|0|Rn:4
+ {0x0fe000f0, 0x00c00090, 4, arm_SMULL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMULL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|1|0|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+ {0x0ff0f0b0, 0x012000a0, 4, arm_SMULWB_EQ, 0x6011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMULW<y><c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|0|0|1|0|Rd:4|0|0|0|0|Rm:4|1|M|1|0|Rn:4
+ {0x0ff0f0d0, 0x0700f050, 4, arm_SMUSD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // SMUSD{X}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|0|Rd:4|1|1|1|1|Rm:4|0|1|M|1|Rn:4
+ {0x0ff00ff0, 0x06a00f30, 4, arm_SSAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4m1, arm_arg_R_0}}, // SSAT16<c> <Rd>,#<sat_imm4m1>,<Rn> cond:4|0|1|1|0|1|0|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+ {0x0ff000f0, 0x06a00f30, 3, arm_SSAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4m1, arm_arg_R_0}}, // SSAT16<c> <Rd>,#<sat_imm4m1>,<Rn> cond:4|0|1|1|0|1|0|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+ {0x0fe00030, 0x06a00010, 4, arm_SSAT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm5m1, arm_arg_R_shift_imm}}, // SSAT<c> <Rd>,#<sat_imm5m1>,<Rn>{,<shift>} cond:4|0|1|1|0|1|0|1|sat_imm:5|Rd:4|imm5:5|sh|0|1|Rn:4
+ {0x0ff00ff0, 0x06100f50, 4, arm_SSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x06100f50, 3, arm_SSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06100f70, 4, arm_SSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff000f0, 0x06100f70, 3, arm_SSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff00ff0, 0x06100ff0, 4, arm_SSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x06100ff0, 3, arm_SSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // SSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0fd00000, 0x08800000, 4, arm_STM_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // STM<c> <Rn>{!},<registers> cond:4|1|0|0|0|1|0|W|0|Rn:4|register_list:16
+ {0x0fd00000, 0x08000000, 4, arm_STMDA_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // STMDA<c> <Rn>{!},<registers> cond:4|1|0|0|0|0|0|W|0|Rn:4|register_list:16
+ {0x0fd00000, 0x09000000, 2, arm_STMDB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // STMDB<c> <Rn>{!},<registers> cond:4|1|0|0|1|0|0|W|0|Rn:4|register_list:16
+ {0x0fd00000, 0x09800000, 4, arm_STMIB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}}, // STMIB<c> <Rn>{!},<registers> cond:4|1|0|0|1|1|0|W|0|Rn:4|register_list:16
+ {0x0e500018, 0x06000000, 2, arm_STR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}}, // STR<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|0|W|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0e500000, 0x04000000, 2, arm_STR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}}, // STR<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|0|W|0|Rn:4|Rt:4|imm12:12
+ {0x0e500010, 0x06400000, 2, arm_STRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}}, // STRB<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|1|W|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0e500000, 0x04400000, 2, arm_STRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}}, // STRB<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|1|W|0|Rn:4|Rt:4|imm12:12
+ {0x0f700000, 0x04600000, 4, arm_STRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}}, // STRBT<c> <Rt>,[<Rn>],#+/-<imm12> cond:4|0|1|0|0|U|1|1|0|Rn:4|Rt:4|imm12:12
+ {0x0f700010, 0x06600000, 4, arm_STRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}}, // STRBT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|1|1|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0e500ff0, 0x000000f0, 4, arm_STRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}}, // STRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|1|1|Rm:4
+ {0x0e5000f0, 0x000000f0, 3, arm_STRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}}, // STRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|1|1|Rm:4
+ {0x0e5000f0, 0x004000f0, 4, arm_STRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_imm8_W}}, // STRD<c> <Rt1>,<Rt2>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
+ {0x0ff00ff0, 0x01800f90, 4, arm_STREX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}}, // STREX<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+ {0x0ff00ff0, 0x01c00f90, 4, arm_STREXB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}}, // STREXB<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|1|0|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+ {0x0ff00ff0, 0x01a00f90, 4, arm_STREXD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R1_0, arm_arg_R2_0, arm_arg_mem_R}}, // STREXD<c> <Rd>,<Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+ {0x0ff00ff0, 0x01e00f90, 4, arm_STREXH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}}, // STREXH<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|1|1|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+ {0x0e500ff0, 0x000000b0, 2, arm_STRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}}, // STRH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+ {0x0e5000f0, 0x004000b0, 2, arm_STRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}}, // STRH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+ {0x0f7000f0, 0x006000b0, 4, arm_STRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}}, // STRHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|0|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+ {0x0f700ff0, 0x002000b0, 4, arm_STRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}}, // STRHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|0|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+ {0x0f700000, 0x04200000, 4, arm_STRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}}, // STRT<c> <Rt>, [<Rn>] {,#+/-<imm12>} cond:4|0|1|0|0|U|0|1|0|Rn:4|Rt:4|imm12:12
+ {0x0f700010, 0x06200000, 4, arm_STRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}}, // STRT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|0|1|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+ {0x0fe00000, 0x02400000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // SUB{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|1|0|S|Rn:4|Rd:4|imm12:12
+ {0x0fe00090, 0x00400010, 4, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // SUB{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+ {0x0fe00010, 0x00400000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // SUB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0fef0000, 0x024d0000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_const}}, // SUB{S}<c> <Rd>,SP,#<const> cond:4|0|0|1|0|0|1|0|S|1|1|0|1|Rd:4|imm12:12
+ {0x0fef0010, 0x004d0000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_R_shift_imm}}, // SUB{S}<c> <Rd>,SP,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4
+ {0x0f000000, 0x0f000000, 4, arm_SVC_EQ, 0x1c04, arm_instArgs{arm_arg_imm24}}, // SVC<c> #<imm24> cond:4|1|1|1|1|imm24:24
+ {0x0fb00ff0, 0x01000090, 4, arm_SWP_EQ, 0x16011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}}, // SWP{B}<c> <Rt>,<Rm>,[<Rn>] cond:4|0|0|0|1|0|B|0|0|Rn:4|Rt:4|0|0|0|0|1|0|0|1|Rm:4
+ {0x0ff003f0, 0x06800070, 2, arm_SXTAB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}}, // SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0ff003f0, 0x06a00070, 2, arm_SXTAB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}}, // SXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0ff003f0, 0x06b00070, 2, arm_SXTAH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}}, // SXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|1|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fff03f0, 0x068f0070, 4, arm_SXTB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}}, // SXTB16<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|0|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fff03f0, 0x06af0070, 4, arm_SXTB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}}, // SXTB<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fff03f0, 0x06bf0070, 4, arm_SXTH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}}, // SXTH<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|1|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0ff0f000, 0x03300000, 4, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // TEQ<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff00000, 0x03300000, 3, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // TEQ<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff0f090, 0x01300010, 4, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // TEQ<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff00090, 0x01300010, 3, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // TEQ<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff0f010, 0x01300000, 4, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // TEQ<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff00010, 0x01300000, 3, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // TEQ<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff0f000, 0x03100000, 4, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // TST<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff00000, 0x03100000, 3, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // TST<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+ {0x0ff0f090, 0x01100010, 4, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // TST<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff00090, 0x01100010, 3, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // TST<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+ {0x0ff0f010, 0x01100000, 4, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // TST<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff00010, 0x01100000, 3, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // TST<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+ {0x0ff00ff0, 0x06500f10, 4, arm_UADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x06500f10, 3, arm_UADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06500f90, 4, arm_UADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff000f0, 0x06500f90, 3, arm_UADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06500f30, 4, arm_UASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06500f30, 3, arm_UASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0fe00070, 0x07e00050, 4, arm_UBFX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_widthm1}}, // UBFX<c> <Rd>,<Rn>,#<lsb>,#<widthm1> cond:4|0|1|1|1|1|1|1|widthm1:5|Rd:4|lsb:5|1|0|1|Rn:4
+ {0x0ff00ff0, 0x06700f10, 4, arm_UHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x06700f10, 3, arm_UHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06700f90, 4, arm_UHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff000f0, 0x06700f90, 3, arm_UHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06700f30, 4, arm_UHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06700f30, 3, arm_UHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff00ff0, 0x06700f50, 4, arm_UHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x06700f50, 3, arm_UHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06700f70, 4, arm_UHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff000f0, 0x06700f70, 3, arm_UHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff00ff0, 0x06700ff0, 4, arm_UHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x06700ff0, 3, arm_UHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x00400090, 4, arm_UMAAL_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // UMAAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|0|1|0|0|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+ {0x0fe000f0, 0x00a00090, 4, arm_UMLAL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // UMLAL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|0|1|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+ {0x0fe000f0, 0x00800090, 4, arm_UMULL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // UMULL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|0|0|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+ {0x0ff00ff0, 0x06600f10, 4, arm_UQADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff000f0, 0x06600f10, 3, arm_UQADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06600f90, 4, arm_UQADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff000f0, 0x06600f90, 3, arm_UQADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+ {0x0ff00ff0, 0x06600f30, 4, arm_UQASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff000f0, 0x06600f30, 3, arm_UQASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+ {0x0ff00ff0, 0x06600f50, 4, arm_UQSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x06600f50, 3, arm_UQSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06600f70, 4, arm_UQSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff000f0, 0x06600f70, 3, arm_UQSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff00ff0, 0x06600ff0, 4, arm_UQSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x06600ff0, 3, arm_UQSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // UQSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff0f0f0, 0x0780f010, 4, arm_USAD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}}, // USAD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|1|0|0|0|Rd:4|1|1|1|1|Rm:4|0|0|0|1|Rn:4
+ {0x0ff000f0, 0x07800010, 2, arm_USADA8_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}}, // USADA8<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|1|0|0|0|Rd:4|Ra:4|Rm:4|0|0|0|1|Rn:4
+ {0x0ff00ff0, 0x06e00f30, 4, arm_USAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4, arm_arg_R_0}}, // USAT16<c> <Rd>,#<sat_imm4>,<Rn> cond:4|0|1|1|0|1|1|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+ {0x0ff000f0, 0x06e00f30, 3, arm_USAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4, arm_arg_R_0}}, // USAT16<c> <Rd>,#<sat_imm4>,<Rn> cond:4|0|1|1|0|1|1|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+ {0x0fe00030, 0x06e00010, 4, arm_USAT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm5, arm_arg_R_shift_imm}}, // USAT<c> <Rd>,#<sat_imm5>,<Rn>{,<shift>} cond:4|0|1|1|0|1|1|1|sat_imm:5|Rd:4|imm5:5|sh|0|1|Rn:4
+ {0x0ff00ff0, 0x06500f50, 4, arm_USAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // USAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff000f0, 0x06500f50, 3, arm_USAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // USAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+ {0x0ff00ff0, 0x06500f70, 4, arm_USUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // USUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff000f0, 0x06500f70, 3, arm_USUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // USUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+ {0x0ff00ff0, 0x06500ff0, 4, arm_USUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // USUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff000f0, 0x06500ff0, 3, arm_USUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}}, // USUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+ {0x0ff003f0, 0x06c00070, 2, arm_UXTAB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}}, // UXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|0|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0ff003f0, 0x06e00070, 2, arm_UXTAB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}}, // UXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0ff003f0, 0x06f00070, 2, arm_UXTAH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}}, // UXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|1|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fff03f0, 0x06cf0070, 4, arm_UXTB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}}, // UXTB16<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|0|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fff03f0, 0x06ef0070, 4, arm_UXTB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}}, // UXTB<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fff03f0, 0x06ff0070, 4, arm_UXTH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}}, // UXTH<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|1|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+ {0x0fb00e10, 0x0e000a00, 4, arm_VMLA_EQ_F32, 0x60108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // V<MLA,MLS><c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|0|0|Vn:4|Vd:4|1|0|1|sz|N|op|M|0|Vm:4
+ {0x0fbf0ed0, 0x0eb00ac0, 4, arm_VABS_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}}, // VABS<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|0|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
+ {0x0fb00e50, 0x0e300a00, 4, arm_VADD_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // VADD<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|1|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
+ {0x0fbf0e7f, 0x0eb50a40, 4, arm_VCMP_EQ_F32, 0x70108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_fp_0}}, // VCMP{E}<c>.F<32,64> <Sd,Dd>, #0.0 cond:4|1|1|1|0|1|D|1|1|0|1|0|1|Vd:4|1|0|1|sz|E|1|0|0|(0)|(0)|(0)|(0)
+ {0x0fbf0e70, 0x0eb50a40, 3, arm_VCMP_EQ_F32, 0x70108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_fp_0}}, // VCMP{E}<c>.F<32,64> <Sd,Dd>, #0.0 cond:4|1|1|1|0|1|D|1|1|0|1|0|1|Vd:4|1|0|1|sz|E|1|0|0|(0)|(0)|(0)|(0)
+ {0x0fbf0e50, 0x0eb40a40, 4, arm_VCMP_EQ_F32, 0x70108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}}, // VCMP{E}<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|1|0|0|Vd:4|1|0|1|sz|E|1|M|0|Vm:4
+ {0x0fbe0e50, 0x0eba0a40, 4, arm_VCVT_EQ_F32_FXS16, 0x801100107011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sd_Dd, arm_arg_fbits}}, // VCVT<c>.F<32,64>.FX<S,U><16,32> <Sd,Dd>, <Sd,Dd>, #<fbits> cond:4|1|1|1|0|1|D|1|1|1|0|1|U|Vd:4|1|0|1|sz|sx|1|i|0|imm4:4
+ {0x0fbe0e50, 0x0ebe0a40, 4, arm_VCVT_EQ_FXS16_F32, 0x1001070108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sd_Dd, arm_arg_fbits}}, // VCVT<c>.FX<S,U><16,32>.F<32,64> <Sd,Dd>, <Sd,Dd>, #<fbits> cond:4|1|1|1|0|1|D|1|1|1|1|1|U|Vd:4|1|0|1|sz|sx|1|i|0|imm4:4
+ {0x0fbf0ed0, 0x0eb70ac0, 4, arm_VCVT_EQ_F64_F32, 0x8011c04, arm_instArgs{arm_arg_Dd_Sd, arm_arg_Sm_Dm}}, // VCVT<c>.<F64.F32,F32.F64> <Dd,Sd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|1|1|1|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
+ {0x0fbe0f50, 0x0eb20a40, 4, arm_VCVTB_EQ_F32_F16, 0x70110011c04, arm_instArgs{arm_arg_Sd, arm_arg_Sm}}, // VCVT<B,T><c>.<F32.F16,F16.F32> <Sd>, <Sm> cond:4|1|1|1|0|1|D|1|1|0|0|1|op|Vd:4|1|0|1|0|T|1|M|0|Vm:4
+ {0x0fbf0e50, 0x0eb80a40, 4, arm_VCVT_EQ_F32_U32, 0x80107011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm}}, // VCVT<c>.F<32,64>.<U,S>32 <Sd,Dd>, <Sm> cond:4|1|1|1|0|1|D|1|1|1|0|0|0|Vd:4|1|0|1|sz|op|1|M|0|Vm:4
+ {0x0fbe0e50, 0x0ebc0a40, 4, arm_VCVTR_EQ_U32_F32, 0x701100108011c04, arm_instArgs{arm_arg_Sd, arm_arg_Sm_Dm}}, // VCVT<R,><c>.<U,S>32.F<32,64> <Sd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|1|1|0|signed|Vd:4|1|0|1|sz|op|1|M|0|Vm:4
+ {0x0fb00e50, 0x0e800a00, 4, arm_VDIV_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // VDIV<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|1|D|0|0|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
+ {0x0f300e00, 0x0d100a00, 4, arm_VLDR_EQ, 0x1c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_mem_R_pm_imm8at0_offset}}, // VLDR<c> <Sd,Dd>, [<Rn>{,#+/-<imm8>}] cond:4|1|1|0|1|U|D|0|1|Rn:4|Vd:4|1|0|1|sz|imm8:8
+ {0x0ff00f7f, 0x0e000a10, 4, arm_VMOV_EQ, 0x1c04, arm_instArgs{arm_arg_Sn, arm_arg_R_12}}, // VMOV<c> <Sn>, <Rt> cond:4|1|1|1|0|0|0|0|0|Vn:4|Rt:4|1|0|1|0|N|0|0|1|0|0|0|0
+ {0x0ff00f7f, 0x0e100a10, 4, arm_VMOV_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_Sn}}, // VMOV<c> <Rt>, <Sn> cond:4|1|1|1|0|0|0|0|1|Vn:4|Rt:4|1|0|1|0|N|0|0|1|0|0|0|0
+ {0x0fd00f7f, 0x0e100b10, 4, arm_VMOV_EQ_32, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_Dn_half}}, // VMOV<c>.32 <Rt>, <Dn[x]> cond:4|1|1|1|0|0|0|opc1|1|Vn:4|Rt:4|1|0|1|1|N|0|0|1|0|0|0|0
+ {0x0fd00f7f, 0x0e000b10, 4, arm_VMOV_EQ_32, 0x1c04, arm_instArgs{arm_arg_Dn_half, arm_arg_R_12}}, // VMOV<c>.32 <Dd[x]>, <Rt> cond:4|1|1|1|0|0|0|opc1|0|Vd:4|Rt:4|1|0|1|1|D|0|0|1|0|0|0|0
+ {0x0fb00ef0, 0x0eb00a00, 4, arm_VMOV_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_imm_vfp}}, // VMOV<c>.F<32,64> <Sd,Dd>, #<imm_vfp> cond:4|1|1|1|0|1|D|1|1|imm4H:4|Vd:4|1|0|1|sz|0|0|0|0|imm4L:4
+ {0x0fbf0ed0, 0x0eb00a40, 4, arm_VMOV_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}}, // VMOV<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|0|Vd:4|1|0|1|sz|0|1|M|0|Vm:4
+ {0x0fff0fff, 0x0ef10a10, 4, arm_VMRS_EQ, 0x1c04, arm_instArgs{arm_arg_R_12_nzcv, arm_arg_FPSCR}}, // VMRS<c> <Rt_nzcv>, FPSCR cond:4|1|1|1|0|1|1|1|1|0|0|0|1|Rt:4|1|0|1|0|0|0|0|1|0|0|0|0
+ {0x0fff0fff, 0x0ee10a10, 4, arm_VMSR_EQ, 0x1c04, arm_instArgs{arm_arg_FPSCR, arm_arg_R_12}}, // VMSR<c> FPSCR, <Rt> cond:4|1|1|1|0|1|1|1|0|0|0|0|1|Rt:4|1|0|1|0|0|0|0|1|0|0|0|0
+ {0x0fb00e50, 0x0e200a00, 4, arm_VMUL_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // VMUL<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|0|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
+ {0x0fbf0ed0, 0x0eb10a40, 4, arm_VNEG_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}}, // VNEG<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|1|Vd:4|1|0|1|sz|0|1|M|0|Vm:4
+ {0x0fb00e10, 0x0e100a00, 4, arm_VNMLS_EQ_F32, 0x60108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // VN<MLS,MLA><c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|0|1|Vn:4|Vd:4|1|0|1|sz|N|op|M|0|Vm:4
+ {0x0fb00e50, 0x0e200a40, 4, arm_VNMUL_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // VNMUL<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|0|Vn:4|Vd:4|1|0|1|sz|N|1|M|0|Vm:4
+ {0x0fbf0ed0, 0x0eb10ac0, 4, arm_VSQRT_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}}, // VSQRT<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|1|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
+ {0x0f300e00, 0x0d000a00, 4, arm_VSTR_EQ, 0x1c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_mem_R_pm_imm8at0_offset}}, // VSTR<c> <Sd,Dd>, [<Rn>{,#+/-<imm8>}] cond:4|1|1|0|1|U|D|0|0|Rn:4|Vd:4|1|0|1|sz|imm8:8
+ {0x0fb00e50, 0x0e300a40, 4, arm_VSUB_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}}, // VSUB<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|1|Vn:4|Vd:4|1|0|1|sz|N|1|M|0|Vm:4
+ {0x0fffffff, 0x0320f002, 4, arm_WFE_EQ, 0x1c04, arm_instArgs{}}, // WFE<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|0
+ {0x0fff00ff, 0x0320f002, 3, arm_WFE_EQ, 0x1c04, arm_instArgs{}}, // WFE<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|0
+ {0x0fffffff, 0x0320f003, 4, arm_WFI_EQ, 0x1c04, arm_instArgs{}}, // WFI<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|1
+ {0x0fff00ff, 0x0320f003, 3, arm_WFI_EQ, 0x1c04, arm_instArgs{}}, // WFI<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|1
+ {0x0fffffff, 0x0320f001, 4, arm_YIELD_EQ, 0x1c04, arm_instArgs{}}, // YIELD<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|1
+ {0x0fff00ff, 0x0320f001, 3, arm_YIELD_EQ, 0x1c04, arm_instArgs{}}, // YIELD<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|1
+ {0xffffffff, 0xf7fabcfd, 4, arm_UNDEF, 0x0, arm_instArgs{}}, // UNDEF 1|1|1|1|0|1|1|1|1|1|1|1|1|0|1|0|1|0|1|1|1|1|0|0|1|1|1|1|1|1|0|1
+}
diff --git a/src/cmd/objdump/elf.go b/src/cmd/objdump/elf.go
new file mode 100644
index 000000000..906e90353
--- /dev/null
+++ b/src/cmd/objdump/elf.go
@@ -0,0 +1,65 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of ELF executables (Linux, FreeBSD, and so on).
+
+package main
+
+import (
+ "debug/elf"
+ "os"
+)
+
+func elfSymbols(f *os.File) (syms []Sym, goarch string) {
+ p, err := elf.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return
+ }
+
+ elfSyms, err := p.Symbols()
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return
+ }
+
+ switch p.Machine {
+ case elf.EM_X86_64:
+ goarch = "amd64"
+ case elf.EM_386:
+ goarch = "386"
+ case elf.EM_ARM:
+ goarch = "arm"
+ }
+
+ for _, s := range elfSyms {
+ sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
+ switch s.Section {
+ case elf.SHN_UNDEF:
+ sym.Code = 'U'
+ case elf.SHN_COMMON:
+ sym.Code = 'B'
+ default:
+ i := int(s.Section)
+ if i < 0 || i >= len(p.Sections) {
+ break
+ }
+ sect := p.Sections[i]
+ switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
+ case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
+ sym.Code = 'T'
+ case elf.SHF_ALLOC:
+ sym.Code = 'R'
+ case elf.SHF_ALLOC | elf.SHF_WRITE:
+ sym.Code = 'D'
+ }
+ }
+ if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
+ sym.Code += 'a' - 'A'
+ }
+ syms = append(syms, sym)
+ }
+
+ return
+}
diff --git a/src/cmd/objdump/macho.go b/src/cmd/objdump/macho.go
new file mode 100644
index 000000000..6e0ad223d
--- /dev/null
+++ b/src/cmd/objdump/macho.go
@@ -0,0 +1,77 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Mach-O executables (OS X).
+
+package main
+
+import (
+ "debug/macho"
+ "os"
+ "sort"
+)
+
+func machoSymbols(f *os.File) (syms []Sym, goarch string) {
+ p, err := macho.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return
+ }
+
+ if p.Symtab == nil {
+ errorf("%s: no symbol table", f.Name())
+ return
+ }
+
+ switch p.Cpu {
+ case macho.Cpu386:
+ goarch = "386"
+ case macho.CpuAmd64:
+ goarch = "amd64"
+ case macho.CpuArm:
+ goarch = "arm"
+ }
+
+ // Build sorted list of addresses of all symbols.
+ // We infer the size of a symbol by looking at where the next symbol begins.
+ var addrs []uint64
+ for _, s := range p.Symtab.Syms {
+ addrs = append(addrs, s.Value)
+ }
+ sort.Sort(uint64s(addrs))
+
+ for _, s := range p.Symtab.Syms {
+ sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
+ i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
+ if i < len(addrs) {
+ sym.Size = int64(addrs[i] - s.Value)
+ }
+ if s.Sect == 0 {
+ sym.Code = 'U'
+ } else if int(s.Sect) <= len(p.Sections) {
+ sect := p.Sections[s.Sect-1]
+ switch sect.Seg {
+ case "__TEXT":
+ sym.Code = 'R'
+ case "__DATA":
+ sym.Code = 'D'
+ }
+ switch sect.Seg + " " + sect.Name {
+ case "__TEXT __text":
+ sym.Code = 'T'
+ case "__DATA __bss", "__DATA __noptrbss":
+ sym.Code = 'B'
+ }
+ }
+ syms = append(syms, sym)
+ }
+
+ return
+}
+
+type uint64s []uint64
+
+func (x uint64s) Len() int { return len(x) }
+func (x uint64s) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
diff --git a/src/cmd/objdump/main.c b/src/cmd/objdump/main.c
deleted file mode 100644
index b684be7fb..000000000
--- a/src/cmd/objdump/main.c
+++ /dev/null
@@ -1,68 +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.
-
-/*
- * objdump simulation - only enough to make pprof work on Macs
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-
-void
-usage(void)
-{
- fprint(2, "usage: objdump binary start stop\n");
- fprint(2, "Disassembles binary from PC start up to stop.\n");
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- int fd, n;
- uvlong pc, start, stop;
- Fhdr fhdr;
- Biobuf bout;
- char buf[1024];
- Map *text;
-
- ARGBEGIN{
- default:
- usage();
- }ARGEND
-
- if(argc != 3)
- usage();
- start = strtoull(argv[1], 0, 16);
- stop = strtoull(argv[2], 0, 16);
-
- fd = open(argv[0], OREAD);
- if(fd < 0)
- sysfatal("open %s: %r", argv[0]);
- if(crackhdr(fd, &fhdr) <= 0)
- sysfatal("crackhdr: %r");
- machbytype(fhdr.type);
- if(syminit(fd, &fhdr) <= 0)
- sysfatal("syminit: %r");
- text = loadmap(nil, fd, &fhdr);
- if(text == nil)
- sysfatal("loadmap: %r");
-
- Binit(&bout, 1, OWRITE);
- for(pc=start; pc<stop; ) {
- if(fileline(buf, sizeof buf, pc))
- Bprint(&bout, "%s\n", buf);
- buf[0] = '\0';
- machdata->das(text, pc, 0, buf, sizeof buf);
- Bprint(&bout, " %llx: %s\n", pc, buf);
- n = machdata->instsize(text, pc);
- if(n <= 0)
- break;
- pc += n;
- }
- Bflush(&bout);
- exits(0);
-}
diff --git a/src/cmd/objdump/main.go b/src/cmd/objdump/main.go
new file mode 100644
index 000000000..ade54366e
--- /dev/null
+++ b/src/cmd/objdump/main.go
@@ -0,0 +1,519 @@
+// 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.
+
+// Objdump disassembles executable files.
+//
+// Usage:
+//
+// go tool objdump [-s symregexp] binary
+//
+// Objdump prints a disassembly of all text symbols (code) in the binary.
+// If the -s option is present, objdump only disassembles
+// symbols with names matching the regular expression.
+//
+// Alternate usage:
+//
+// go tool objdump binary start end
+//
+// In this mode, objdump disassembles the binary starting at the start address and
+// stopping at the end address. The start and end addresses are program
+// counters written in hexadecimal with optional leading 0x prefix.
+// In this mode, objdump prints a sequence of stanzas of the form:
+//
+// file:line
+// address: assembly
+// address: assembly
+// ...
+//
+// Each stanza gives the disassembly for a contiguous range of addresses
+// all mapped to the same original source file and line number.
+// This mode is intended for use by pprof.
+//
+// The ARM disassembler is missing (golang.org/issue/7452) but will be added
+// before the Go 1.3 release.
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "debug/elf"
+ "debug/gosym"
+ "debug/macho"
+ "debug/pe"
+ "debug/plan9obj"
+ "encoding/binary"
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "text/tabwriter"
+)
+
+var symregexp = flag.String("s", "", "only dump symbols matching this regexp")
+var symRE *regexp.Regexp
+
+func usage() {
+ fmt.Fprintf(os.Stderr, "usage: go tool objdump [-s symregexp] binary [start end]\n\n")
+ flag.PrintDefaults()
+ os.Exit(2)
+}
+
+type lookupFunc func(addr uint64) (sym string, base uint64)
+type disasmFunc func(code []byte, pc uint64, lookup lookupFunc) (text string, size int)
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("objdump: ")
+
+ flag.Usage = usage
+ flag.Parse()
+ if flag.NArg() != 1 && flag.NArg() != 3 {
+ usage()
+ }
+
+ if *symregexp != "" {
+ re, err := regexp.Compile(*symregexp)
+ if err != nil {
+ log.Fatalf("invalid -s regexp: %v", err)
+ }
+ symRE = re
+ }
+
+ f, err := os.Open(flag.Arg(0))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ textStart, textData, symtab, pclntab, err := loadTables(f)
+ if err != nil {
+ log.Fatalf("reading %s: %v", flag.Arg(0), err)
+ }
+
+ syms, goarch, err := loadSymbols(f)
+ if err != nil {
+ log.Fatalf("reading %s: %v", flag.Arg(0), err)
+ }
+
+ // Filter out section symbols, overwriting syms in place.
+ keep := syms[:0]
+ for _, sym := range syms {
+ switch sym.Name {
+ case "text", "_text", "etext", "_etext":
+ // drop
+ default:
+ keep = append(keep, sym)
+ }
+ }
+ syms = keep
+
+ disasm := disasms[goarch]
+ if disasm == nil {
+ log.Fatalf("reading %s: unknown architecture", flag.Arg(0))
+ }
+
+ lookup := func(addr uint64) (string, uint64) {
+ i := sort.Search(len(syms), func(i int) bool { return syms[i].Addr > addr })
+ if i > 0 {
+ s := syms[i-1]
+ if s.Addr <= addr && addr < s.Addr+uint64(s.Size) && s.Name != "etext" && s.Name != "_etext" {
+ return s.Name, s.Addr
+ }
+ }
+ return "", 0
+ }
+
+ pcln := gosym.NewLineTable(pclntab, textStart)
+ tab, err := gosym.NewTable(symtab, pcln)
+ if err != nil {
+ log.Fatalf("reading %s: %v", flag.Arg(0), err)
+ }
+
+ if flag.NArg() == 1 {
+ // disassembly of entire object - our format
+ dump(tab, lookup, disasm, goarch, syms, textData, textStart)
+ os.Exit(exitCode)
+ }
+
+ // disassembly of specific piece of object - gnu objdump format for pprof
+ gnuDump(tab, lookup, disasm, textData, textStart)
+ os.Exit(exitCode)
+}
+
+// base returns the final element in the path.
+// It works on both Windows and Unix paths.
+func base(path string) string {
+ path = path[strings.LastIndex(path, "/")+1:]
+ path = path[strings.LastIndex(path, `\`)+1:]
+ return path
+}
+
+func dump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, goarch string, syms []Sym, textData []byte, textStart uint64) {
+ stdout := bufio.NewWriter(os.Stdout)
+ defer stdout.Flush()
+
+ printed := false
+ for _, sym := range syms {
+ if sym.Code != 'T' || sym.Size == 0 || sym.Name == "_text" || sym.Name == "text" || sym.Addr < textStart || symRE != nil && !symRE.MatchString(sym.Name) {
+ continue
+ }
+ if sym.Addr >= textStart+uint64(len(textData)) || sym.Addr+uint64(sym.Size) > textStart+uint64(len(textData)) {
+ break
+ }
+ if printed {
+ fmt.Fprintf(stdout, "\n")
+ } else {
+ printed = true
+ }
+ file, _, _ := tab.PCToLine(sym.Addr)
+ fmt.Fprintf(stdout, "TEXT %s(SB) %s\n", sym.Name, file)
+ tw := tabwriter.NewWriter(stdout, 1, 8, 1, '\t', 0)
+ start := sym.Addr
+ end := sym.Addr + uint64(sym.Size)
+ for pc := start; pc < end; {
+ i := pc - textStart
+ text, size := disasm(textData[i:end-textStart], pc, lookup)
+ file, line, _ := tab.PCToLine(pc)
+
+ // ARM is word-based, so show actual word hex, not byte hex.
+ // Since ARM is little endian, they're different.
+ if goarch == "arm" && size == 4 {
+ fmt.Fprintf(tw, "\t%s:%d\t%#x\t%08x\t%s\n", base(file), line, pc, binary.LittleEndian.Uint32(textData[i:i+uint64(size)]), text)
+ } else {
+ fmt.Fprintf(tw, "\t%s:%d\t%#x\t%x\t%s\n", base(file), line, pc, textData[i:i+uint64(size)], text)
+ }
+ pc += uint64(size)
+ }
+ tw.Flush()
+ }
+}
+
+func disasm_386(code []byte, pc uint64, lookup lookupFunc) (string, int) {
+ return disasm_x86(code, pc, lookup, 32)
+}
+
+func disasm_amd64(code []byte, pc uint64, lookup lookupFunc) (string, int) {
+ return disasm_x86(code, pc, lookup, 64)
+}
+
+func disasm_x86(code []byte, pc uint64, lookup lookupFunc, arch int) (string, int) {
+ inst, err := x86_Decode(code, 64)
+ var text string
+ size := inst.Len
+ if err != nil || size == 0 || inst.Op == 0 {
+ size = 1
+ text = "?"
+ } else {
+ text = x86_plan9Syntax(inst, pc, lookup)
+ }
+ return text, size
+}
+
+type textReader struct {
+ code []byte
+ pc uint64
+}
+
+func (r textReader) ReadAt(data []byte, off int64) (n int, err error) {
+ if off < 0 || uint64(off) < r.pc {
+ return 0, io.EOF
+ }
+ d := uint64(off) - r.pc
+ if d >= uint64(len(r.code)) {
+ return 0, io.EOF
+ }
+ n = copy(data, r.code[d:])
+ if n < len(data) {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+func disasm_arm(code []byte, pc uint64, lookup lookupFunc) (string, int) {
+ inst, err := arm_Decode(code, arm_ModeARM)
+ var text string
+ size := inst.Len
+ if err != nil || size == 0 || inst.Op == 0 {
+ size = 4
+ text = "?"
+ } else {
+ text = arm_plan9Syntax(inst, pc, lookup, textReader{code, pc})
+ }
+ return text, size
+}
+
+var disasms = map[string]disasmFunc{
+ "386": disasm_386,
+ "amd64": disasm_amd64,
+ "arm": disasm_arm,
+}
+
+func gnuDump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, textData []byte, textStart uint64) {
+ start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64)
+ if err != nil {
+ log.Fatalf("invalid start PC: %v", err)
+ }
+ end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64)
+ if err != nil {
+ log.Fatalf("invalid end PC: %v", err)
+ }
+ if start < textStart {
+ start = textStart
+ }
+ if end < start {
+ end = start
+ }
+ if end > textStart+uint64(len(textData)) {
+ end = textStart + uint64(len(textData))
+ }
+
+ stdout := bufio.NewWriter(os.Stdout)
+ defer stdout.Flush()
+
+ // For now, find spans of same PC/line/fn and
+ // emit them as having dummy instructions.
+ var (
+ spanPC uint64
+ spanFile string
+ spanLine int
+ spanFn *gosym.Func
+ )
+
+ flush := func(endPC uint64) {
+ if spanPC == 0 {
+ return
+ }
+ fmt.Fprintf(stdout, "%s:%d\n", spanFile, spanLine)
+ for pc := spanPC; pc < endPC; {
+ text, size := disasm(textData[pc-textStart:], pc, lookup)
+ fmt.Fprintf(stdout, " %x: %s\n", pc, text)
+ pc += uint64(size)
+ }
+ spanPC = 0
+ }
+
+ for pc := start; pc < end; pc++ {
+ file, line, fn := tab.PCToLine(pc)
+ if file != spanFile || line != spanLine || fn != spanFn {
+ flush(pc)
+ spanPC, spanFile, spanLine, spanFn = pc, file, line, fn
+ }
+ }
+ flush(end)
+}
+
+func loadTables(f *os.File) (textStart uint64, textData, symtab, pclntab []byte, err error) {
+ if obj, err := elf.NewFile(f); err == nil {
+ if sect := obj.Section(".text"); sect != nil {
+ textStart = sect.Addr
+ textData, _ = sect.Data()
+ }
+ if sect := obj.Section(".gosymtab"); sect != nil {
+ if symtab, err = sect.Data(); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ }
+ if sect := obj.Section(".gopclntab"); sect != nil {
+ if pclntab, err = sect.Data(); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ }
+ return textStart, textData, symtab, pclntab, nil
+ }
+
+ if obj, err := macho.NewFile(f); err == nil {
+ if sect := obj.Section("__text"); sect != nil {
+ textStart = sect.Addr
+ textData, _ = sect.Data()
+ }
+ if sect := obj.Section("__gosymtab"); sect != nil {
+ if symtab, err = sect.Data(); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ }
+ if sect := obj.Section("__gopclntab"); sect != nil {
+ if pclntab, err = sect.Data(); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ }
+ return textStart, textData, symtab, pclntab, nil
+ }
+
+ if obj, err := pe.NewFile(f); err == nil {
+ var imageBase uint64
+ switch oh := obj.OptionalHeader.(type) {
+ case *pe.OptionalHeader32:
+ imageBase = uint64(oh.ImageBase)
+ case *pe.OptionalHeader64:
+ imageBase = oh.ImageBase
+ default:
+ return 0, nil, nil, nil, fmt.Errorf("pe file format not recognized")
+ }
+ if sect := obj.Section(".text"); sect != nil {
+ textStart = imageBase + uint64(sect.VirtualAddress)
+ textData, _ = sect.Data()
+ }
+ if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ return textStart, textData, symtab, pclntab, nil
+ }
+
+ if obj, err := plan9obj.NewFile(f); err == nil {
+ sym, err := findPlan9Symbol(obj, "text")
+ if err != nil {
+ return 0, nil, nil, nil, err
+ }
+ textStart = sym.Value
+ if sect := obj.Section("text"); sect != nil {
+ textData, _ = sect.Data()
+ }
+ if pclntab, err = loadPlan9Table(obj, "pclntab", "epclntab"); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ if symtab, err = loadPlan9Table(obj, "symtab", "esymtab"); err != nil {
+ return 0, nil, nil, nil, err
+ }
+ return textStart, textData, symtab, pclntab, nil
+ }
+
+ return 0, nil, nil, nil, fmt.Errorf("unrecognized binary format")
+}
+
+func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
+ for _, s := range f.Symbols {
+ if s.Name != name {
+ continue
+ }
+ if s.SectionNumber <= 0 {
+ return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
+ }
+ if len(f.Sections) < int(s.SectionNumber) {
+ return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
+ }
+ return s, nil
+ }
+ return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
+ ssym, err := findPESymbol(f, sname)
+ if err != nil {
+ return nil, err
+ }
+ esym, err := findPESymbol(f, ename)
+ if err != nil {
+ return nil, err
+ }
+ if ssym.SectionNumber != esym.SectionNumber {
+ return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
+ }
+ sect := f.Sections[ssym.SectionNumber-1]
+ data, err := sect.Data()
+ if err != nil {
+ return nil, err
+ }
+ return data[ssym.Value:esym.Value], nil
+}
+
+func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
+ syms, err := f.Symbols()
+ if err != nil {
+ return nil, err
+ }
+ for _, s := range syms {
+ if s.Name != name {
+ continue
+ }
+ return &s, nil
+ }
+ return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
+ ssym, err := findPlan9Symbol(f, sname)
+ if err != nil {
+ return nil, err
+ }
+ esym, err := findPlan9Symbol(f, ename)
+ if err != nil {
+ return nil, err
+ }
+ text, err := findPlan9Symbol(f, "text")
+ if err != nil {
+ return nil, err
+ }
+ sect := f.Section("text")
+ if sect == nil {
+ return nil, err
+ }
+ data, err := sect.Data()
+ if err != nil {
+ return nil, err
+ }
+ return data[ssym.Value-text.Value : esym.Value-text.Value], nil
+}
+
+// TODO(rsc): This code is taken from cmd/nm. Arrange some way to share the code.
+
+var exitCode = 0
+
+func errorf(format string, args ...interface{}) {
+ log.Printf(format, args...)
+ exitCode = 1
+}
+
+func loadSymbols(f *os.File) (syms []Sym, goarch string, err error) {
+ f.Seek(0, 0)
+ buf := make([]byte, 16)
+ io.ReadFull(f, buf)
+ f.Seek(0, 0)
+
+ for _, p := range parsers {
+ if bytes.HasPrefix(buf, p.prefix) {
+ syms, goarch = p.parse(f)
+ sort.Sort(byAddr(syms))
+ return
+ }
+ }
+ err = fmt.Errorf("unknown file format")
+ return
+}
+
+type Sym struct {
+ Addr uint64
+ Size int64
+ Code rune
+ Name string
+ Type string
+}
+
+var parsers = []struct {
+ prefix []byte
+ parse func(*os.File) ([]Sym, string)
+}{
+ {[]byte("\x7FELF"), elfSymbols},
+ {[]byte("\xFE\xED\xFA\xCE"), machoSymbols},
+ {[]byte("\xFE\xED\xFA\xCF"), machoSymbols},
+ {[]byte("\xCE\xFA\xED\xFE"), machoSymbols},
+ {[]byte("\xCF\xFA\xED\xFE"), machoSymbols},
+ {[]byte("MZ"), peSymbols},
+ {[]byte("\x00\x00\x01\xEB"), plan9Symbols}, // 386
+ {[]byte("\x00\x00\x04\x07"), plan9Symbols}, // mips
+ {[]byte("\x00\x00\x06\x47"), plan9Symbols}, // arm
+ {[]byte("\x00\x00\x8A\x97"), plan9Symbols}, // amd64
+}
+
+type byAddr []Sym
+
+func (x byAddr) Len() int { return len(x) }
+func (x byAddr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
new file mode 100644
index 000000000..82311bb1f
--- /dev/null
+++ b/src/cmd/objdump/objdump_test.go
@@ -0,0 +1,193 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "testing"
+)
+
+func loadSyms(t *testing.T) map[string]string {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ cmd := exec.Command("go", "tool", "nm", os.Args[0])
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ syms := make(map[string]string)
+ scanner := bufio.NewScanner(bytes.NewReader(out))
+ for scanner.Scan() {
+ f := strings.Fields(scanner.Text())
+ if len(f) < 3 {
+ continue
+ }
+ syms[f[2]] = f[0]
+ }
+ if err := scanner.Err(); err != nil {
+ t.Fatalf("error reading symbols: %v", err)
+ }
+ return syms
+}
+
+func runObjDump(t *testing.T, exe, startaddr, endaddr string) (path, lineno string) {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ cmd := exec.Command(exe, os.Args[0], startaddr, endaddr)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool objdump %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ f := strings.Split(string(out), "\n")
+ if len(f) < 1 {
+ t.Fatal("objdump output must have at least one line")
+ }
+ pathAndLineNo := f[0]
+ f = strings.Split(pathAndLineNo, ":")
+ if runtime.GOOS == "windows" {
+ switch len(f) {
+ case 2:
+ return f[0], f[1]
+ case 3:
+ return f[0] + ":" + f[1], f[2]
+ default:
+ t.Fatalf("no line number found in %q", pathAndLineNo)
+ }
+ }
+ if len(f) != 2 {
+ t.Fatalf("no line number found in %q", pathAndLineNo)
+ }
+ return f[0], f[1]
+}
+
+func testObjDump(t *testing.T, exe, startaddr, endaddr string, line int) {
+ srcPath, srcLineNo := runObjDump(t, exe, startaddr, endaddr)
+ fi1, err := os.Stat("objdump_test.go")
+ if err != nil {
+ t.Fatalf("Stat failed: %v", err)
+ }
+ fi2, err := os.Stat(srcPath)
+ if err != nil {
+ t.Fatalf("Stat failed: %v", err)
+ }
+ if !os.SameFile(fi1, fi2) {
+ t.Fatalf("objdump_test.go and %s are not same file", srcPath)
+ }
+ if srcLineNo != fmt.Sprint(line) {
+ t.Fatalf("line number = %v; want %d", srcLineNo, line)
+ }
+}
+
+func TestObjDump(t *testing.T) {
+ _, _, line, _ := runtime.Caller(0)
+ syms := loadSyms(t)
+
+ tmp, exe := buildObjdump(t)
+ defer os.RemoveAll(tmp)
+
+ startaddr := syms["cmd/objdump.TestObjDump"]
+ addr, err := strconv.ParseUint(startaddr, 16, 64)
+ if err != nil {
+ t.Fatalf("invalid start address %v: %v", startaddr, err)
+ }
+ endaddr := fmt.Sprintf("%x", addr+10)
+ testObjDump(t, exe, startaddr, endaddr, line-1)
+ testObjDump(t, exe, "0x"+startaddr, "0x"+endaddr, line-1)
+}
+
+func buildObjdump(t *testing.T) (tmp, exe string) {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ tmp, err := ioutil.TempDir("", "TestObjDump")
+ if err != nil {
+ t.Fatal("TempDir failed: ", err)
+ }
+
+ exe = filepath.Join(tmp, "testobjdump.exe")
+ out, err := exec.Command("go", "build", "-o", exe, "cmd/objdump").CombinedOutput()
+ if err != nil {
+ os.RemoveAll(tmp)
+ t.Fatalf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out))
+ }
+ return
+}
+
+var x86Need = []string{
+ "fmthello.go:6",
+ "TEXT main.main(SB)",
+ "JMP main.main(SB)",
+ "CALL fmt.Println(SB)",
+ "RET",
+}
+
+var armNeed = []string{
+ "fmthello.go:6",
+ "TEXT main.main(SB)",
+ "B.LS main.main(SB)",
+ "BL fmt.Println(SB)",
+ "RET",
+}
+
+// objdump is fully cross platform: it can handle binaries
+// from any known operating system and architecture.
+// We could in principle add binaries to testdata and check
+// all the supported systems during this test. However, the
+// binaries would be about 1 MB each, and we don't want to
+// add that much junk to the hg repository. Instead, build a
+// binary for the current system (only) and test that objdump
+// can handle that one.
+
+func TestDisasm(t *testing.T) {
+ tmp, exe := buildObjdump(t)
+ defer os.RemoveAll(tmp)
+
+ hello := filepath.Join(tmp, "hello.exe")
+ out, err := exec.Command("go", "build", "-o", hello, "testdata/fmthello.go").CombinedOutput()
+ if err != nil {
+ t.Fatalf("go build fmthello.go: %v\n%s", err, out)
+ }
+ need := []string{
+ "fmthello.go:6",
+ "TEXT main.main(SB)",
+ }
+ switch runtime.GOARCH {
+ case "amd64", "386":
+ need = append(need, x86Need...)
+ case "arm":
+ need = append(need, armNeed...)
+ }
+
+ out, err = exec.Command(exe, "-s", "main.main", hello).CombinedOutput()
+ if err != nil {
+ t.Fatalf("objdump fmthello.exe: %v\n%s", err, out)
+ }
+
+ text := string(out)
+ ok := true
+ for _, s := range need {
+ if !strings.Contains(text, s) {
+ t.Errorf("disassembly missing '%s'", s)
+ ok = false
+ }
+ }
+ if !ok {
+ t.Logf("full disassembly:\n%s", text)
+ }
+}
diff --git a/src/cmd/objdump/pe.go b/src/cmd/objdump/pe.go
new file mode 100644
index 000000000..38190095a
--- /dev/null
+++ b/src/cmd/objdump/pe.go
@@ -0,0 +1,99 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of PE executables (Microsoft Windows).
+
+package main
+
+import (
+ "debug/pe"
+ "os"
+ "sort"
+)
+
+func peSymbols(f *os.File) (syms []Sym, goarch string) {
+ p, err := pe.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return
+ }
+
+ // Build sorted list of addresses of all symbols.
+ // We infer the size of a symbol by looking at where the next symbol begins.
+ var addrs []uint64
+
+ var imageBase uint64
+ switch oh := p.OptionalHeader.(type) {
+ case *pe.OptionalHeader32:
+ imageBase = uint64(oh.ImageBase)
+ goarch = "386"
+ case *pe.OptionalHeader64:
+ imageBase = oh.ImageBase
+ goarch = "amd64"
+ default:
+ errorf("parsing %s: file format not recognized", f.Name())
+ return
+ }
+
+ for _, s := range p.Symbols {
+ const (
+ N_UNDEF = 0 // An undefined (extern) symbol
+ N_ABS = -1 // An absolute symbol (e_value is a constant, not an address)
+ N_DEBUG = -2 // A debugging symbol
+ )
+ sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
+ switch s.SectionNumber {
+ case N_UNDEF:
+ sym.Code = 'U'
+ case N_ABS:
+ sym.Code = 'C'
+ case N_DEBUG:
+ sym.Code = '?'
+ default:
+ if s.SectionNumber < 0 {
+ errorf("parsing %s: invalid section number %d", f.Name(), s.SectionNumber)
+ return
+ }
+ if len(p.Sections) < int(s.SectionNumber) {
+ errorf("parsing %s: section number %d is large then max %d", f.Name(), s.SectionNumber, len(p.Sections))
+ return
+ }
+ sect := p.Sections[s.SectionNumber-1]
+ const (
+ text = 0x20
+ data = 0x40
+ bss = 0x80
+ permX = 0x20000000
+ permR = 0x40000000
+ permW = 0x80000000
+ )
+ ch := sect.Characteristics
+ switch {
+ case ch&text != 0:
+ sym.Code = 'T'
+ case ch&data != 0:
+ if ch&permW == 0 {
+ sym.Code = 'R'
+ } else {
+ sym.Code = 'D'
+ }
+ case ch&bss != 0:
+ sym.Code = 'B'
+ }
+ sym.Addr += imageBase + uint64(sect.VirtualAddress)
+ }
+ syms = append(syms, sym)
+ addrs = append(addrs, sym.Addr)
+ }
+
+ sort.Sort(uint64s(addrs))
+ for i := range syms {
+ j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
+ if j < len(addrs) {
+ syms[i].Size = int64(addrs[j] - syms[i].Addr)
+ }
+ }
+
+ return
+}
diff --git a/src/cmd/objdump/plan9obj.go b/src/cmd/objdump/plan9obj.go
new file mode 100644
index 000000000..34462f31c
--- /dev/null
+++ b/src/cmd/objdump/plan9obj.go
@@ -0,0 +1,63 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Plan 9 a.out executables.
+
+package main
+
+import (
+ "debug/plan9obj"
+ "os"
+ "sort"
+)
+
+var validSymType = map[rune]bool{
+ 'T': true,
+ 't': true,
+ 'D': true,
+ 'd': true,
+ 'B': true,
+ 'b': true,
+}
+
+func plan9Symbols(f *os.File) (syms []Sym, goarch string) {
+ p, err := plan9obj.NewFile(f)
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return
+ }
+
+ plan9Syms, err := p.Symbols()
+ if err != nil {
+ errorf("parsing %s: %v", f.Name(), err)
+ return
+ }
+
+ goarch = "386"
+
+ // Build sorted list of addresses of all symbols.
+ // We infer the size of a symbol by looking at where the next symbol begins.
+ var addrs []uint64
+ for _, s := range plan9Syms {
+ if !validSymType[s.Type] {
+ continue
+ }
+ addrs = append(addrs, s.Value)
+ }
+ sort.Sort(uint64s(addrs))
+
+ for _, s := range plan9Syms {
+ if !validSymType[s.Type] {
+ continue
+ }
+ sym := Sym{Addr: s.Value, Name: s.Name, Code: rune(s.Type)}
+ i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
+ if i < len(addrs) {
+ sym.Size = int64(addrs[i] - s.Value)
+ }
+ syms = append(syms, sym)
+ }
+
+ return
+}
diff --git a/src/cmd/objdump/testdata/fmthello.go b/src/cmd/objdump/testdata/fmthello.go
new file mode 100644
index 000000000..635db7ae6
--- /dev/null
+++ b/src/cmd/objdump/testdata/fmthello.go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("hello, world")
+}
diff --git a/src/cmd/objdump/x86.go b/src/cmd/objdump/x86.go
new file mode 100644
index 000000000..8e741331f
--- /dev/null
+++ b/src/cmd/objdump/x86.go
@@ -0,0 +1,13800 @@
+// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
+// bundle -p main -x x86_ rsc.io/x86/x86asm
+
+/* decode.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Table-driven decoding of x86 instructions.
+
+package main
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "runtime"
+ "strings"
+)
+
+// Set trace to true to cause the decoder to print the PC sequence
+// of the executed instruction codes. This is typically only useful
+// when you are running a test of a single input case.
+const x86_trace = false
+
+// A decodeOp is a single instruction in the decoder bytecode program.
+//
+// The decodeOps correspond to consuming and conditionally branching
+// on input bytes, consuming additional fields, and then interpreting
+// consumed data as instruction arguments. The names of the xRead and xArg
+// operations are taken from the Intel manual conventions, for example
+// Volume 2, Section 3.1.1, page 487 of
+// http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf
+//
+// The actual decoding program is generated by ../x86map.
+//
+// TODO(rsc): We may be able to merge various of the memory operands
+// since we don't care about, say, the distinction between m80dec and m80bcd.
+// Similarly, mm and mm1 have identical meaning, as do xmm and xmm1.
+
+type x86_decodeOp uint16
+
+const (
+ x86_xFail x86_decodeOp = iota // invalid instruction (return)
+ x86_xMatch // completed match
+ x86_xJump // jump to pc
+
+ x86_xCondByte // switch on instruction byte value
+ x86_xCondSlashR // read and switch on instruction /r value
+ x86_xCondPrefix // switch on presence of instruction prefix
+ x86_xCondIs64 // switch on 64-bit processor mode
+ x86_xCondDataSize // switch on operand size
+ x86_xCondAddrSize // switch on address size
+ x86_xCondIsMem // switch on memory vs register argument
+
+ x86_xSetOp // set instruction opcode
+
+ x86_xReadSlashR // read /r
+ x86_xReadIb // read ib
+ x86_xReadIw // read iw
+ x86_xReadId // read id
+ x86_xReadIo // read io
+ x86_xReadCb // read cb
+ x86_xReadCw // read cw
+ x86_xReadCd // read cd
+ x86_xReadCp // read cp
+ x86_xReadCm // read cm
+
+ x86_xArg1 // arg 1
+ x86_xArg3 // arg 3
+ x86_xArgAL // arg AL
+ x86_xArgAX // arg AX
+ x86_xArgCL // arg CL
+ x86_xArgCR0dashCR7 // arg CR0-CR7
+ x86_xArgCS // arg CS
+ x86_xArgDR0dashDR7 // arg DR0-DR7
+ x86_xArgDS // arg DS
+ x86_xArgDX // arg DX
+ x86_xArgEAX // arg EAX
+ x86_xArgEDX // arg EDX
+ x86_xArgES // arg ES
+ x86_xArgFS // arg FS
+ x86_xArgGS // arg GS
+ x86_xArgImm16 // arg imm16
+ x86_xArgImm32 // arg imm32
+ x86_xArgImm64 // arg imm64
+ x86_xArgImm8 // arg imm8
+ x86_xArgImm8u // arg imm8 but record as unsigned
+ x86_xArgImm16u // arg imm8 but record as unsigned
+ x86_xArgM // arg m
+ x86_xArgM128 // arg m128
+ x86_xArgM1428byte // arg m14/28byte
+ x86_xArgM16 // arg m16
+ x86_xArgM16and16 // arg m16&16
+ x86_xArgM16and32 // arg m16&32
+ x86_xArgM16and64 // arg m16&64
+ x86_xArgM16colon16 // arg m16:16
+ x86_xArgM16colon32 // arg m16:32
+ x86_xArgM16colon64 // arg m16:64
+ x86_xArgM16int // arg m16int
+ x86_xArgM2byte // arg m2byte
+ x86_xArgM32 // arg m32
+ x86_xArgM32and32 // arg m32&32
+ x86_xArgM32fp // arg m32fp
+ x86_xArgM32int // arg m32int
+ x86_xArgM512byte // arg m512byte
+ x86_xArgM64 // arg m64
+ x86_xArgM64fp // arg m64fp
+ x86_xArgM64int // arg m64int
+ x86_xArgM8 // arg m8
+ x86_xArgM80bcd // arg m80bcd
+ x86_xArgM80dec // arg m80dec
+ x86_xArgM80fp // arg m80fp
+ x86_xArgM94108byte // arg m94/108byte
+ x86_xArgMm // arg mm
+ x86_xArgMm1 // arg mm1
+ x86_xArgMm2 // arg mm2
+ x86_xArgMm2M64 // arg mm2/m64
+ x86_xArgMmM32 // arg mm/m32
+ x86_xArgMmM64 // arg mm/m64
+ x86_xArgMem // arg mem
+ x86_xArgMoffs16 // arg moffs16
+ x86_xArgMoffs32 // arg moffs32
+ x86_xArgMoffs64 // arg moffs64
+ x86_xArgMoffs8 // arg moffs8
+ x86_xArgPtr16colon16 // arg ptr16:16
+ x86_xArgPtr16colon32 // arg ptr16:32
+ x86_xArgR16 // arg r16
+ x86_xArgR16op // arg r16 with +rw in opcode
+ x86_xArgR32 // arg r32
+ x86_xArgR32M16 // arg r32/m16
+ x86_xArgR32M8 // arg r32/m8
+ x86_xArgR32op // arg r32 with +rd in opcode
+ x86_xArgR64 // arg r64
+ x86_xArgR64M16 // arg r64/m16
+ x86_xArgR64op // arg r64 with +rd in opcode
+ x86_xArgR8 // arg r8
+ x86_xArgR8op // arg r8 with +rb in opcode
+ x86_xArgRAX // arg RAX
+ x86_xArgRDX // arg RDX
+ x86_xArgRM // arg r/m
+ x86_xArgRM16 // arg r/m16
+ x86_xArgRM32 // arg r/m32
+ x86_xArgRM64 // arg r/m64
+ x86_xArgRM8 // arg r/m8
+ x86_xArgReg // arg reg
+ x86_xArgRegM16 // arg reg/m16
+ x86_xArgRegM32 // arg reg/m32
+ x86_xArgRegM8 // arg reg/m8
+ x86_xArgRel16 // arg rel16
+ x86_xArgRel32 // arg rel32
+ x86_xArgRel8 // arg rel8
+ x86_xArgSS // arg SS
+ x86_xArgST // arg ST, aka ST(0)
+ x86_xArgSTi // arg ST(i) with +i in opcode
+ x86_xArgSreg // arg Sreg
+ x86_xArgTR0dashTR7 // arg TR0-TR7
+ x86_xArgXmm // arg xmm
+ x86_xArgXMM0 // arg <XMM0>
+ x86_xArgXmm1 // arg xmm1
+ x86_xArgXmm2 // arg xmm2
+ x86_xArgXmm2M128 // arg xmm2/m128
+ x86_xArgXmm2M16 // arg xmm2/m16
+ x86_xArgXmm2M32 // arg xmm2/m32
+ x86_xArgXmm2M64 // arg xmm2/m64
+ x86_xArgXmmM128 // arg xmm/m128
+ x86_xArgXmmM32 // arg xmm/m32
+ x86_xArgXmmM64 // arg xmm/m64
+ x86_xArgRmf16 // arg r/m16 but force mod=3
+ x86_xArgRmf32 // arg r/m32 but force mod=3
+ x86_xArgRmf64 // arg r/m64 but force mod=3
+)
+
+// instPrefix returns an Inst describing just one prefix byte.
+// It is only used if there is a prefix followed by an unintelligible
+// or invalid instruction byte sequence.
+func x86_instPrefix(b byte, mode int) (x86_Inst, error) {
+ // When tracing it is useful to see what called instPrefix to report an error.
+ if x86_trace {
+ _, file, line, _ := runtime.Caller(1)
+ fmt.Printf("%s:%d\n", file, line)
+ }
+ p := x86_Prefix(b)
+ switch p {
+ case x86_PrefixDataSize:
+ if mode == 16 {
+ p = x86_PrefixData32
+ } else {
+ p = x86_PrefixData16
+ }
+ case x86_PrefixAddrSize:
+ if mode == 32 {
+ p = x86_PrefixAddr16
+ } else {
+ p = x86_PrefixAddr32
+ }
+ }
+ // Note: using composite literal with Prefix key confuses 'bundle' tool.
+ inst := x86_Inst{Len: 1}
+ inst.Prefix = x86_Prefixes{p}
+ return inst, nil
+}
+
+// truncated reports a truncated instruction.
+// For now we use instPrefix but perhaps later we will return
+// a specific error here.
+func x86_truncated(src []byte, mode int) (x86_Inst, error) {
+ // return Inst{}, len(src), ErrTruncated
+ return x86_instPrefix(src[0], mode) // too long
+}
+
+// These are the errors returned by Decode.
+var (
+ x86_ErrInvalidMode = errors.New("invalid x86 mode in Decode")
+ x86_ErrTruncated = errors.New("truncated instruction")
+ x86_ErrUnrecognized = errors.New("unrecognized instruction")
+)
+
+// decoderCover records coverage information for which parts
+// of the byte code have been executed.
+// TODO(rsc): This is for testing. Only use this if a flag is given.
+var x86_decoderCover []bool
+
+// Decode decodes the leading bytes in src as a single instruction.
+// The mode arguments specifies the assumed processor mode:
+// 16, 32, or 64 for 16-, 32-, and 64-bit execution modes.
+func x86_Decode(src []byte, mode int) (inst x86_Inst, err error) {
+ return x86_decode1(src, mode, false)
+}
+
+// decode1 is the implementation of Decode but takes an extra
+// gnuCompat flag to cause it to change its behavior to mimic
+// bugs (or at least unique features) of GNU libopcodes as used
+// by objdump. We don't believe that logic is the right thing to do
+// in general, but when testing against libopcodes it simplifies the
+// comparison if we adjust a few small pieces of logic.
+// The affected logic is in the conditional branch for "mandatory" prefixes,
+// case xCondPrefix.
+func x86_decode1(src []byte, mode int, gnuCompat bool) (x86_Inst, error) {
+ switch mode {
+ case 16, 32, 64:
+ // ok
+ // TODO(rsc): 64-bit mode not tested, probably not working.
+ default:
+ return x86_Inst{}, x86_ErrInvalidMode
+ }
+
+ // Maximum instruction size is 15 bytes.
+ // If we need to read more, return 'truncated instruction.
+ if len(src) > 15 {
+ src = src[:15]
+ }
+
+ var (
+ // prefix decoding information
+ pos = 0 // position reading src
+ nprefix = 0 // number of prefixes
+ lockIndex = -1 // index of LOCK prefix in src and inst.Prefix
+ repIndex = -1 // index of REP/REPN prefix in src and inst.Prefix
+ segIndex = -1 // index of Group 2 prefix in src and inst.Prefix
+ dataSizeIndex = -1 // index of Group 3 prefix in src and inst.Prefix
+ addrSizeIndex = -1 // index of Group 4 prefix in src and inst.Prefix
+ rex x86_Prefix // rex byte if present (or 0)
+ rexUsed x86_Prefix // bits used in rex byte
+ rexIndex = -1 // index of rex byte
+
+ addrMode = mode // address mode (width in bits)
+ dataMode = mode // operand mode (width in bits)
+
+ // decoded ModR/M fields
+ haveModrm bool
+ modrm int
+ mod int
+ regop int
+ rm int
+
+ // if ModR/M is memory reference, Mem form
+ mem x86_Mem
+ haveMem bool
+
+ // decoded SIB fields
+ haveSIB bool
+ sib int
+ scale int
+ index int
+ base int
+
+ // decoded immediate values
+ imm int64
+ imm8 int8
+ immc int64
+
+ // output
+ opshift int
+ inst x86_Inst
+ narg int // number of arguments written to inst
+ )
+
+ if mode == 64 {
+ dataMode = 32
+ }
+
+ // Prefixes are certainly the most complex and underspecified part of
+ // decoding x86 instructions. Although the manuals say things like
+ // up to four prefixes, one from each group, nearly everyone seems to
+ // agree that in practice as many prefixes as possible, including multiple
+ // from a particular group or repetitions of a given prefix, can be used on
+ // an instruction, provided the total instruction length including prefixes
+ // does not exceed the agreed-upon maximum of 15 bytes.
+ // Everyone also agrees that if one of these prefixes is the LOCK prefix
+ // and the instruction is not one of the instructions that can be used with
+ // the LOCK prefix or if the destination is not a memory operand,
+ // then the instruction is invalid and produces the #UD exception.
+ // However, that is the end of any semblance of agreement.
+ //
+ // What happens if prefixes are given that conflict with other prefixes?
+ // For example, the memory segment overrides CS, DS, ES, FS, GS, SS
+ // conflict with each other: only one segment can be in effect.
+ // Disassemblers seem to agree that later prefixes take priority over
+ // earlier ones. I have not taken the time to write assembly programs
+ // to check to see if the hardware agrees.
+ //
+ // What happens if prefixes are given that have no meaning for the
+ // specific instruction to which they are attached? It depends.
+ // If they really have no meaning, they are ignored. However, a future
+ // processor may assign a different meaning. As a disassembler, we
+ // don't really know whether we're seeing a meaningless prefix or one
+ // whose meaning we simply haven't been told yet.
+ //
+ // Combining the two questions, what happens when conflicting
+ // extension prefixes are given? No one seems to know for sure.
+ // For example, MOVQ is 66 0F D6 /r, MOVDQ2Q is F2 0F D6 /r,
+ // and MOVQ2DQ is F3 0F D6 /r. What is '66 F2 F3 0F D6 /r'?
+ // Which prefix wins? See the xCondPrefix prefix for more.
+ //
+ // Writing assembly test cases to divine which interpretation the
+ // CPU uses might clarify the situation, but more likely it would
+ // make the situation even less clear.
+
+ // Read non-REX prefixes.
+ReadPrefixes:
+ for ; pos < len(src); pos++ {
+ p := x86_Prefix(src[pos])
+ switch p {
+ default:
+ nprefix = pos
+ break ReadPrefixes
+
+ // Group 1 - lock and repeat prefixes
+ // According to Intel, there should only be one from this set,
+ // but according to AMD both can be present.
+ case 0xF0:
+ if lockIndex >= 0 {
+ inst.Prefix[lockIndex] |= x86_PrefixIgnored
+ }
+ lockIndex = pos
+ case 0xF2, 0xF3:
+ if repIndex >= 0 {
+ inst.Prefix[repIndex] |= x86_PrefixIgnored
+ }
+ repIndex = pos
+
+ // Group 2 - segment override / branch hints
+ case 0x26, 0x2E, 0x36, 0x3E:
+ if mode == 64 {
+ p |= x86_PrefixIgnored
+ break
+ }
+ fallthrough
+ case 0x64, 0x65:
+ if segIndex >= 0 {
+ inst.Prefix[segIndex] |= x86_PrefixIgnored
+ }
+ segIndex = pos
+
+ // Group 3 - operand size override
+ case 0x66:
+ if mode == 16 {
+ dataMode = 32
+ p = x86_PrefixData32
+ } else {
+ dataMode = 16
+ p = x86_PrefixData16
+ }
+ if dataSizeIndex >= 0 {
+ inst.Prefix[dataSizeIndex] |= x86_PrefixIgnored
+ }
+ dataSizeIndex = pos
+
+ // Group 4 - address size override
+ case 0x67:
+ if mode == 32 {
+ addrMode = 16
+ p = x86_PrefixAddr16
+ } else {
+ addrMode = 32
+ p = x86_PrefixAddr32
+ }
+ if addrSizeIndex >= 0 {
+ inst.Prefix[addrSizeIndex] |= x86_PrefixIgnored
+ }
+ addrSizeIndex = pos
+ }
+
+ if pos >= len(inst.Prefix) {
+ return x86_instPrefix(src[0], mode) // too long
+ }
+
+ inst.Prefix[pos] = p
+ }
+
+ // Read REX prefix.
+ if pos < len(src) && mode == 64 && x86_Prefix(src[pos]).IsREX() {
+ rex = x86_Prefix(src[pos])
+ rexIndex = pos
+ if pos >= len(inst.Prefix) {
+ return x86_instPrefix(src[0], mode) // too long
+ }
+ inst.Prefix[pos] = rex
+ pos++
+ if rex&x86_PrefixREXW != 0 {
+ dataMode = 64
+ if dataSizeIndex >= 0 {
+ inst.Prefix[dataSizeIndex] |= x86_PrefixIgnored
+ }
+ }
+ }
+
+ // Decode instruction stream, interpreting decoding instructions.
+ // opshift gives the shift to use when saving the next
+ // opcode byte into inst.Opcode.
+ opshift = 24
+ if x86_decoderCover == nil {
+ x86_decoderCover = make([]bool, len(x86_decoder))
+ }
+
+ // Decode loop, executing decoder program.
+ var oldPC, prevPC int
+Decode:
+ for pc := 1; ; { // TODO uint
+ oldPC = prevPC
+ prevPC = pc
+ if x86_trace {
+ println("run", pc)
+ }
+ x := x86_decoder[pc]
+ x86_decoderCover[pc] = true
+ pc++
+
+ // Read and decode ModR/M if needed by opcode.
+ switch x86_decodeOp(x) {
+ case x86_xCondSlashR, x86_xReadSlashR:
+ if haveModrm {
+ return x86_Inst{Len: pos}, x86_errInternal
+ }
+ haveModrm = true
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ modrm = int(src[pos])
+ pos++
+ if opshift >= 0 {
+ inst.Opcode |= uint32(modrm) << uint(opshift)
+ opshift -= 8
+ }
+ mod = modrm >> 6
+ regop = (modrm >> 3) & 07
+ rm = modrm & 07
+ if rex&x86_PrefixREXR != 0 {
+ rexUsed |= x86_PrefixREXR
+ regop |= 8
+ }
+ if addrMode == 16 {
+ // 16-bit modrm form
+ if mod != 3 {
+ haveMem = true
+ mem = x86_addr16[rm]
+ if rm == 6 && mod == 0 {
+ mem.Base = 0
+ }
+
+ // Consume disp16 if present.
+ if mod == 0 && rm == 6 || mod == 2 {
+ if pos+2 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ mem.Disp = int64(binary.LittleEndian.Uint16(src[pos:]))
+ pos += 2
+ }
+
+ // Consume disp8 if present.
+ if mod == 1 {
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ mem.Disp = int64(int8(src[pos]))
+ pos++
+ }
+ }
+ } else {
+ haveMem = mod != 3
+
+ // 32-bit or 64-bit form
+ // Consume SIB encoding if present.
+ if rm == 4 && mod != 3 {
+ haveSIB = true
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ sib = int(src[pos])
+ pos++
+ if opshift >= 0 {
+ inst.Opcode |= uint32(sib) << uint(opshift)
+ opshift -= 8
+ }
+ scale = sib >> 6
+ index = (sib >> 3) & 07
+ base = sib & 07
+ if rex&x86_PrefixREXB != 0 {
+ rexUsed |= x86_PrefixREXB
+ base |= 8
+ }
+ if rex&x86_PrefixREXX != 0 {
+ rexUsed |= x86_PrefixREXX
+ index |= 8
+ }
+
+ mem.Scale = 1 << uint(scale)
+ if index == 4 {
+ // no mem.Index
+ } else {
+ mem.Index = x86_baseRegForBits(addrMode) + x86_Reg(index)
+ }
+ if base&7 == 5 && mod == 0 {
+ // no mem.Base
+ } else {
+ mem.Base = x86_baseRegForBits(addrMode) + x86_Reg(base)
+ }
+ } else {
+ if rex&x86_PrefixREXB != 0 {
+ rexUsed |= x86_PrefixREXB
+ rm |= 8
+ }
+ if mod == 0 && rm&7 == 5 || rm&7 == 4 {
+ // base omitted
+ } else if mod != 3 {
+ mem.Base = x86_baseRegForBits(addrMode) + x86_Reg(rm)
+ }
+ }
+
+ // Consume disp32 if present.
+ if mod == 0 && (rm&7 == 5 || haveSIB && base&7 == 5) || mod == 2 {
+ if pos+4 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ mem.Disp = int64(binary.LittleEndian.Uint32(src[pos:]))
+ pos += 4
+ }
+
+ // Consume disp8 if present.
+ if mod == 1 {
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ mem.Disp = int64(int8(src[pos]))
+ pos++
+ }
+
+ // In 64-bit, mod=0 rm=5 is PC-relative instead of just disp.
+ // See Vol 2A. Table 2-7.
+ if mode == 64 && mod == 0 && rm&7 == 5 {
+ if addrMode == 32 {
+ mem.Base = x86_EIP
+ } else {
+ mem.Base = x86_RIP
+ }
+ }
+ }
+
+ if segIndex >= 0 {
+ mem.Segment = x86_prefixToSegment(inst.Prefix[segIndex])
+ }
+ }
+
+ // Execute single opcode.
+ switch x86_decodeOp(x) {
+ default:
+ println("bad op", x, "at", pc-1, "from", oldPC)
+ return x86_Inst{Len: pos}, x86_errInternal
+
+ case x86_xFail:
+ inst.Op = 0
+ break Decode
+
+ case x86_xMatch:
+ break Decode
+
+ case x86_xJump:
+ pc = int(x86_decoder[pc])
+
+ // Conditional branches.
+
+ case x86_xCondByte:
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ b := src[pos]
+ n := int(x86_decoder[pc])
+ pc++
+ for i := 0; i < n; i++ {
+ xb, xpc := x86_decoder[pc], int(x86_decoder[pc+1])
+ pc += 2
+ if b == byte(xb) {
+ pc = xpc
+ pos++
+ if opshift >= 0 {
+ inst.Opcode |= uint32(b) << uint(opshift)
+ opshift -= 8
+ }
+ continue Decode
+ }
+ }
+ // xCondByte is the only conditional with a fall through,
+ // so that it can be used to pick off special cases before
+ // an xCondSlash. If the fallthrough instruction is xFail,
+ // advance the position so that the decoded instruction
+ // size includes the byte we just compared against.
+ if x86_decodeOp(x86_decoder[pc]) == x86_xJump {
+ pc = int(x86_decoder[pc+1])
+ }
+ if x86_decodeOp(x86_decoder[pc]) == x86_xFail {
+ pos++
+ }
+
+ case x86_xCondIs64:
+ if mode == 64 {
+ pc = int(x86_decoder[pc+1])
+ } else {
+ pc = int(x86_decoder[pc])
+ }
+
+ case x86_xCondIsMem:
+ mem := haveMem
+ if !haveModrm {
+ if pos >= len(src) {
+ return x86_instPrefix(src[0], mode) // too long
+ }
+ mem = src[pos]>>6 != 3
+ }
+ if mem {
+ pc = int(x86_decoder[pc+1])
+ } else {
+ pc = int(x86_decoder[pc])
+ }
+
+ case x86_xCondDataSize:
+ switch dataMode {
+ case 16:
+ if dataSizeIndex >= 0 {
+ inst.Prefix[dataSizeIndex] |= x86_PrefixImplicit
+ }
+ pc = int(x86_decoder[pc])
+ case 32:
+ if dataSizeIndex >= 0 {
+ inst.Prefix[dataSizeIndex] |= x86_PrefixImplicit
+ }
+ pc = int(x86_decoder[pc+1])
+ case 64:
+ rexUsed |= x86_PrefixREXW
+ pc = int(x86_decoder[pc+2])
+ }
+
+ case x86_xCondAddrSize:
+ switch addrMode {
+ case 16:
+ if addrSizeIndex >= 0 {
+ inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
+ }
+ pc = int(x86_decoder[pc])
+ case 32:
+ if addrSizeIndex >= 0 {
+ inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
+ }
+ pc = int(x86_decoder[pc+1])
+ case 64:
+ pc = int(x86_decoder[pc+2])
+ }
+
+ case x86_xCondPrefix:
+ // Conditional branch based on presence or absence of prefixes.
+ // The conflict cases here are completely undocumented and
+ // differ significantly between GNU libopcodes and Intel xed.
+ // I have not written assembly code to divine what various CPUs
+ // do, but it wouldn't surprise me if they are not consistent either.
+ //
+ // The basic idea is to switch on the presence of a prefix, so that
+ // for example:
+ //
+ // xCondPrefix, 4
+ // 0xF3, 123,
+ // 0xF2, 234,
+ // 0x66, 345,
+ // 0, 456
+ //
+ // branch to 123 if the F3 prefix is present, 234 if the F2 prefix
+ // is present, 66 if the 345 prefix is present, and 456 otherwise.
+ // The prefixes are given in descending order so that the 0 will be last.
+ //
+ // It is unclear what should happen if multiple conditions are
+ // satisfied: what if F2 and F3 are both present, or if 66 and F2
+ // are present, or if all three are present? The one chosen becomes
+ // part of the opcode and the others do not. Perhaps the answer
+ // depends on the specific opcodes in question.
+ //
+ // The only clear example is that CRC32 is F2 0F 38 F1 /r, and
+ // it comes in 16-bit and 32-bit forms based on the 66 prefix,
+ // so 66 F2 0F 38 F1 /r should be treated as F2 taking priority,
+ // with the 66 being only an operand size override, and probably
+ // F2 66 0F 38 F1 /r should be treated the same.
+ // Perhaps that rule is specific to the case of CRC32, since no
+ // 66 0F 38 F1 instruction is defined (today) (that we know of).
+ // However, both libopcodes and xed seem to generalize this
+ // example and choose F2/F3 in preference to 66, and we
+ // do the same.
+ //
+ // Next, what if both F2 and F3 are present? Which wins?
+ // The Intel xed rule, and ours, is that the one that occurs last wins.
+ // The GNU libopcodes rule, which we implement only in gnuCompat mode,
+ // is that F3 beats F2 unless F3 has no special meaning, in which
+ // case F3 can be a modified on an F2 special meaning.
+ //
+ // Concretely,
+ // 66 0F D6 /r is MOVQ
+ // F2 0F D6 /r is MOVDQ2Q
+ // F3 0F D6 /r is MOVQ2DQ.
+ //
+ // F2 66 0F D6 /r is 66 + MOVDQ2Q always.
+ // 66 F2 0F D6 /r is 66 + MOVDQ2Q always.
+ // F3 66 0F D6 /r is 66 + MOVQ2DQ always.
+ // 66 F3 0F D6 /r is 66 + MOVQ2DQ always.
+ // F2 F3 0F D6 /r is F2 + MOVQ2DQ always.
+ // F3 F2 0F D6 /r is F3 + MOVQ2DQ in Intel xed, but F2 + MOVQ2DQ in GNU libopcodes.
+ // Adding 66 anywhere in the prefix section of the
+ // last two cases does not change the outcome.
+ //
+ // Finally, what if there is a variant in which 66 is a mandatory
+ // prefix rather than an operand size override, but we know of
+ // no corresponding F2/F3 form, and we see both F2/F3 and 66.
+ // Does F2/F3 still take priority, so that the result is an unknown
+ // instruction, or does the 66 take priority, so that the extended
+ // 66 instruction should be interpreted as having a REP/REPN prefix?
+ // Intel xed does the former and GNU libopcodes does the latter.
+ // We side with Intel xed, unless we are trying to match libopcodes
+ // more closely during the comparison-based test suite.
+ //
+ // In 64-bit mode REX.W is another valid prefix to test for, but
+ // there is less ambiguity about that. When present, REX.W is
+ // always the first entry in the table.
+ n := int(x86_decoder[pc])
+ pc++
+ sawF3 := false
+ for j := 0; j < n; j++ {
+ prefix := x86_Prefix(x86_decoder[pc+2*j])
+ if prefix.IsREX() {
+ rexUsed |= prefix
+ if rex&prefix == prefix {
+ pc = int(x86_decoder[pc+2*j+1])
+ continue Decode
+ }
+ continue
+ }
+ ok := false
+ if prefix == 0 {
+ ok = true
+ } else if prefix.IsREX() {
+ rexUsed |= prefix
+ if rex&prefix == prefix {
+ ok = true
+ }
+ } else {
+ if prefix == 0xF3 {
+ sawF3 = true
+ }
+ switch prefix {
+ case x86_PrefixLOCK:
+ if lockIndex >= 0 {
+ inst.Prefix[lockIndex] |= x86_PrefixImplicit
+ ok = true
+ }
+ case x86_PrefixREP, x86_PrefixREPN:
+ if repIndex >= 0 && inst.Prefix[repIndex]&0xFF == prefix {
+ inst.Prefix[repIndex] |= x86_PrefixImplicit
+ ok = true
+ }
+ if gnuCompat && !ok && prefix == 0xF3 && repIndex >= 0 && (j+1 >= n || x86_decoder[pc+2*(j+1)] != 0xF2) {
+ // Check to see if earlier prefix F3 is present.
+ for i := repIndex - 1; i >= 0; i-- {
+ if inst.Prefix[i]&0xFF == prefix {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ ok = true
+ }
+ }
+ }
+ if gnuCompat && !ok && prefix == 0xF2 && repIndex >= 0 && !sawF3 && inst.Prefix[repIndex]&0xFF == 0xF3 {
+ // Check to see if earlier prefix F2 is present.
+ for i := repIndex - 1; i >= 0; i-- {
+ if inst.Prefix[i]&0xFF == prefix {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ ok = true
+ }
+ }
+ }
+ case x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
+ if segIndex >= 0 && inst.Prefix[segIndex]&0xFF == prefix {
+ inst.Prefix[segIndex] |= x86_PrefixImplicit
+ ok = true
+ }
+ case x86_PrefixDataSize:
+ // Looking for 66 mandatory prefix.
+ // The F2/F3 mandatory prefixes take priority when both are present.
+ // If we got this far in the xCondPrefix table and an F2/F3 is present,
+ // it means the table didn't have any entry for that prefix. But if 66 has
+ // special meaning, perhaps F2/F3 have special meaning that we don't know.
+ // Intel xed works this way, treating the F2/F3 as inhibiting the 66.
+ // GNU libopcodes allows the 66 to match. We do what Intel xed does
+ // except in gnuCompat mode.
+ if repIndex >= 0 && !gnuCompat {
+ inst.Op = 0
+ break Decode
+ }
+ if dataSizeIndex >= 0 {
+ inst.Prefix[dataSizeIndex] |= x86_PrefixImplicit
+ ok = true
+ }
+ case x86_PrefixAddrSize:
+ if addrSizeIndex >= 0 {
+ inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
+ ok = true
+ }
+ }
+ }
+ if ok {
+ pc = int(x86_decoder[pc+2*j+1])
+ continue Decode
+ }
+ }
+ inst.Op = 0
+ break Decode
+
+ case x86_xCondSlashR:
+ pc = int(x86_decoder[pc+regop&7])
+
+ // Input.
+
+ case x86_xReadSlashR:
+ // done above
+
+ case x86_xReadIb:
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ imm8 = int8(src[pos])
+ pos++
+
+ case x86_xReadIw:
+ if pos+2 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ imm = int64(binary.LittleEndian.Uint16(src[pos:]))
+ pos += 2
+
+ case x86_xReadId:
+ if pos+4 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ imm = int64(binary.LittleEndian.Uint32(src[pos:]))
+ pos += 4
+
+ case x86_xReadIo:
+ if pos+8 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ imm = int64(binary.LittleEndian.Uint64(src[pos:]))
+ pos += 8
+
+ case x86_xReadCb:
+ if pos >= len(src) {
+ return x86_truncated(src, mode)
+ }
+ immc = int64(src[pos])
+ pos++
+
+ case x86_xReadCw:
+ if pos+2 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ immc = int64(binary.LittleEndian.Uint16(src[pos:]))
+ pos += 2
+
+ case x86_xReadCm:
+ if addrMode == 16 {
+ if pos+2 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ immc = int64(binary.LittleEndian.Uint16(src[pos:]))
+ pos += 2
+ } else if addrMode == 32 {
+ if pos+4 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ immc = int64(binary.LittleEndian.Uint32(src[pos:]))
+ pos += 4
+ } else {
+ if pos+8 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ immc = int64(binary.LittleEndian.Uint64(src[pos:]))
+ pos += 8
+ }
+ case x86_xReadCd:
+ if pos+4 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ immc = int64(binary.LittleEndian.Uint32(src[pos:]))
+ pos += 4
+
+ case x86_xReadCp:
+ if pos+6 > len(src) {
+ return x86_truncated(src, mode)
+ }
+ w := binary.LittleEndian.Uint32(src[pos:])
+ w2 := binary.LittleEndian.Uint16(src[pos+4:])
+ immc = int64(w2)<<32 | int64(w)
+ pos += 6
+
+ // Output.
+
+ case x86_xSetOp:
+ inst.Op = x86_Op(x86_decoder[pc])
+ pc++
+
+ case x86_xArg1,
+ x86_xArg3,
+ x86_xArgAL,
+ x86_xArgAX,
+ x86_xArgCL,
+ x86_xArgCS,
+ x86_xArgDS,
+ x86_xArgDX,
+ x86_xArgEAX,
+ x86_xArgEDX,
+ x86_xArgES,
+ x86_xArgFS,
+ x86_xArgGS,
+ x86_xArgRAX,
+ x86_xArgRDX,
+ x86_xArgSS,
+ x86_xArgST,
+ x86_xArgXMM0:
+ inst.Args[narg] = x86_fixedArg[x]
+ narg++
+
+ case x86_xArgImm8:
+ inst.Args[narg] = x86_Imm(imm8)
+ narg++
+
+ case x86_xArgImm8u:
+ inst.Args[narg] = x86_Imm(uint8(imm8))
+ narg++
+
+ case x86_xArgImm16:
+ inst.Args[narg] = x86_Imm(int16(imm))
+ narg++
+
+ case x86_xArgImm16u:
+ inst.Args[narg] = x86_Imm(uint16(imm))
+ narg++
+
+ case x86_xArgImm32:
+ inst.Args[narg] = x86_Imm(int32(imm))
+ narg++
+
+ case x86_xArgImm64:
+ inst.Args[narg] = x86_Imm(imm)
+ narg++
+
+ case x86_xArgM,
+ x86_xArgM128,
+ x86_xArgM1428byte,
+ x86_xArgM16,
+ x86_xArgM16and16,
+ x86_xArgM16and32,
+ x86_xArgM16and64,
+ x86_xArgM16colon16,
+ x86_xArgM16colon32,
+ x86_xArgM16colon64,
+ x86_xArgM16int,
+ x86_xArgM2byte,
+ x86_xArgM32,
+ x86_xArgM32and32,
+ x86_xArgM32fp,
+ x86_xArgM32int,
+ x86_xArgM512byte,
+ x86_xArgM64,
+ x86_xArgM64fp,
+ x86_xArgM64int,
+ x86_xArgM8,
+ x86_xArgM80bcd,
+ x86_xArgM80dec,
+ x86_xArgM80fp,
+ x86_xArgM94108byte,
+ x86_xArgMem:
+ if !haveMem {
+ inst.Op = 0
+ break Decode
+ }
+ inst.Args[narg] = mem
+ inst.MemBytes = int(x86_memBytes[x86_decodeOp(x)])
+ narg++
+
+ case x86_xArgPtr16colon16:
+ inst.Args[narg] = x86_Imm(immc >> 16)
+ inst.Args[narg+1] = x86_Imm(immc & (1<<16 - 1))
+ narg += 2
+
+ case x86_xArgPtr16colon32:
+ inst.Args[narg] = x86_Imm(immc >> 32)
+ inst.Args[narg+1] = x86_Imm(immc & (1<<32 - 1))
+ narg += 2
+
+ case x86_xArgMoffs8, x86_xArgMoffs16, x86_xArgMoffs32, x86_xArgMoffs64:
+ // TODO(rsc): Can address be 64 bits?
+ mem = x86_Mem{Disp: int64(immc)}
+ if segIndex >= 0 {
+ mem.Segment = x86_prefixToSegment(inst.Prefix[segIndex])
+ inst.Prefix[segIndex] |= x86_PrefixImplicit
+ }
+ inst.Args[narg] = mem
+ inst.MemBytes = int(x86_memBytes[x86_decodeOp(x)])
+ narg++
+
+ case x86_xArgR8, x86_xArgR16, x86_xArgR32, x86_xArgR64, x86_xArgXmm, x86_xArgXmm1, x86_xArgDR0dashDR7:
+ base := x86_baseReg[x]
+ index := x86_Reg(regop)
+ if rex != 0 && base == x86_AL && index >= 4 {
+ rexUsed |= x86_PrefixREX
+ index -= 4
+ base = x86_SPB
+ }
+ inst.Args[narg] = base + index
+ narg++
+
+ case x86_xArgMm, x86_xArgMm1, x86_xArgTR0dashTR7:
+ inst.Args[narg] = x86_baseReg[x] + x86_Reg(regop&7)
+ narg++
+
+ case x86_xArgCR0dashCR7:
+ // AMD documents an extension that the LOCK prefix
+ // can be used in place of a REX prefix in order to access
+ // CR8 from 32-bit mode. The LOCK prefix is allowed in
+ // all modes, provided the corresponding CPUID bit is set.
+ if lockIndex >= 0 {
+ inst.Prefix[lockIndex] |= x86_PrefixImplicit
+ regop += 8
+ }
+ inst.Args[narg] = x86_CR0 + x86_Reg(regop)
+ narg++
+
+ case x86_xArgSreg:
+ regop &= 7
+ if regop >= 6 {
+ inst.Op = 0
+ break Decode
+ }
+ inst.Args[narg] = x86_ES + x86_Reg(regop)
+ narg++
+
+ case x86_xArgRmf16, x86_xArgRmf32, x86_xArgRmf64:
+ base := x86_baseReg[x]
+ index := x86_Reg(modrm & 07)
+ if rex&x86_PrefixREXB != 0 {
+ rexUsed |= x86_PrefixREXB
+ index += 8
+ }
+ inst.Args[narg] = base + index
+ narg++
+
+ case x86_xArgR8op, x86_xArgR16op, x86_xArgR32op, x86_xArgR64op, x86_xArgSTi:
+ n := inst.Opcode >> uint(opshift+8) & 07
+ base := x86_baseReg[x]
+ index := x86_Reg(n)
+ if rex&x86_PrefixREXB != 0 && x86_decodeOp(x) != x86_xArgSTi {
+ rexUsed |= x86_PrefixREXB
+ index += 8
+ }
+ if rex != 0 && base == x86_AL && index >= 4 {
+ rexUsed |= x86_PrefixREX
+ index -= 4
+ base = x86_SPB
+ }
+ inst.Args[narg] = base + index
+ narg++
+
+ case x86_xArgRM8, x86_xArgRM16, x86_xArgRM32, x86_xArgRM64, x86_xArgR32M16, x86_xArgR32M8, x86_xArgR64M16,
+ x86_xArgMmM32, x86_xArgMmM64, x86_xArgMm2M64,
+ x86_xArgXmm2M16, x86_xArgXmm2M32, x86_xArgXmm2M64, x86_xArgXmmM64, x86_xArgXmmM128, x86_xArgXmmM32, x86_xArgXmm2M128:
+ if haveMem {
+ inst.Args[narg] = mem
+ inst.MemBytes = int(x86_memBytes[x86_decodeOp(x)])
+ } else {
+ base := x86_baseReg[x]
+ index := x86_Reg(rm)
+ switch x86_decodeOp(x) {
+ case x86_xArgMmM32, x86_xArgMmM64, x86_xArgMm2M64:
+ // There are only 8 MMX registers, so these ignore the REX.X bit.
+ index &= 7
+ case x86_xArgRM8:
+ if rex != 0 && index >= 4 {
+ rexUsed |= x86_PrefixREX
+ index -= 4
+ base = x86_SPB
+ }
+ }
+ inst.Args[narg] = base + index
+ }
+ narg++
+
+ case x86_xArgMm2: // register only; TODO(rsc): Handle with tag modrm_regonly tag
+ if haveMem {
+ inst.Op = 0
+ break Decode
+ }
+ inst.Args[narg] = x86_baseReg[x] + x86_Reg(rm&7)
+ narg++
+
+ case x86_xArgXmm2: // register only; TODO(rsc): Handle with tag modrm_regonly tag
+ if haveMem {
+ inst.Op = 0
+ break Decode
+ }
+ inst.Args[narg] = x86_baseReg[x] + x86_Reg(rm)
+ narg++
+
+ case x86_xArgRel8:
+ inst.Args[narg] = x86_Rel(int8(immc))
+ narg++
+
+ case x86_xArgRel16:
+ inst.Args[narg] = x86_Rel(int16(immc))
+ narg++
+
+ case x86_xArgRel32:
+ inst.Args[narg] = x86_Rel(int32(immc))
+ narg++
+ }
+ }
+
+ if inst.Op == 0 {
+ // Invalid instruction.
+ if nprefix > 0 {
+ return x86_instPrefix(src[0], mode) // invalid instruction
+ }
+ return x86_Inst{Len: pos}, x86_ErrUnrecognized
+ }
+
+ // Matched! Hooray!
+
+ // 90 decodes as XCHG EAX, EAX but is NOP.
+ // 66 90 decodes as XCHG AX, AX and is NOP too.
+ // 48 90 decodes as XCHG RAX, RAX and is NOP too.
+ // 43 90 decodes as XCHG R8D, EAX and is *not* NOP.
+ // F3 90 decodes as REP XCHG EAX, EAX but is PAUSE.
+ // It's all too special to handle in the decoding tables, at least for now.
+ if inst.Op == x86_XCHG && inst.Opcode>>24 == 0x90 {
+ if inst.Args[0] == x86_RAX || inst.Args[0] == x86_EAX || inst.Args[0] == x86_AX {
+ inst.Op = x86_NOP
+ if dataSizeIndex >= 0 {
+ inst.Prefix[dataSizeIndex] &^= x86_PrefixImplicit
+ }
+ inst.Args[0] = nil
+ inst.Args[1] = nil
+ }
+ if repIndex >= 0 && inst.Prefix[repIndex] == 0xF3 {
+ inst.Prefix[repIndex] |= x86_PrefixImplicit
+ inst.Op = x86_PAUSE
+ inst.Args[0] = nil
+ inst.Args[1] = nil
+ } else if gnuCompat {
+ for i := nprefix - 1; i >= 0; i-- {
+ if inst.Prefix[i]&0xFF == 0xF3 {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ inst.Op = x86_PAUSE
+ inst.Args[0] = nil
+ inst.Args[1] = nil
+ break
+ }
+ }
+ }
+ }
+
+ // defaultSeg returns the default segment for an implicit
+ // memory reference: the final override if present, or else DS.
+ defaultSeg := func() x86_Reg {
+ if segIndex >= 0 {
+ inst.Prefix[segIndex] |= x86_PrefixImplicit
+ return x86_prefixToSegment(inst.Prefix[segIndex])
+ }
+ return x86_DS
+ }
+
+ // Add implicit arguments not present in the tables.
+ // Normally we shy away from making implicit arguments explicit,
+ // following the Intel manuals, but adding the arguments seems
+ // the best way to express the effect of the segment override prefixes.
+ // TODO(rsc): Perhaps add these to the tables and
+ // create bytecode instructions for them.
+ usedAddrSize := false
+ switch inst.Op {
+ case x86_INSB, x86_INSW, x86_INSD:
+ inst.Args[0] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
+ inst.Args[1] = x86_DX
+ usedAddrSize = true
+
+ case x86_OUTSB, x86_OUTSW, x86_OUTSD:
+ inst.Args[0] = x86_DX
+ inst.Args[1] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
+ usedAddrSize = true
+
+ case x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ:
+ inst.Args[0] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
+ inst.Args[1] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
+ usedAddrSize = true
+
+ case x86_CMPSB, x86_CMPSW, x86_CMPSD, x86_CMPSQ:
+ inst.Args[0] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
+ inst.Args[1] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
+ usedAddrSize = true
+
+ case x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ:
+ switch inst.Op {
+ case x86_LODSB:
+ inst.Args[0] = x86_AL
+ case x86_LODSW:
+ inst.Args[0] = x86_AX
+ case x86_LODSD:
+ inst.Args[0] = x86_EAX
+ case x86_LODSQ:
+ inst.Args[0] = x86_RAX
+ }
+ inst.Args[1] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
+ usedAddrSize = true
+
+ case x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ:
+ inst.Args[0] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
+ switch inst.Op {
+ case x86_STOSB:
+ inst.Args[1] = x86_AL
+ case x86_STOSW:
+ inst.Args[1] = x86_AX
+ case x86_STOSD:
+ inst.Args[1] = x86_EAX
+ case x86_STOSQ:
+ inst.Args[1] = x86_RAX
+ }
+ usedAddrSize = true
+
+ case x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ:
+ inst.Args[1] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
+ switch inst.Op {
+ case x86_SCASB:
+ inst.Args[0] = x86_AL
+ case x86_SCASW:
+ inst.Args[0] = x86_AX
+ case x86_SCASD:
+ inst.Args[0] = x86_EAX
+ case x86_SCASQ:
+ inst.Args[0] = x86_RAX
+ }
+ usedAddrSize = true
+
+ case x86_XLATB:
+ inst.Args[0] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_BX - x86_AX}
+ usedAddrSize = true
+ }
+
+ // If we used the address size annotation to construct the
+ // argument list, mark that prefix as implicit: it doesn't need
+ // to be shown when printing the instruction.
+ if haveMem || usedAddrSize {
+ if addrSizeIndex >= 0 {
+ inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
+ }
+ }
+
+ // Similarly, if there's some memory operand, the segment
+ // will be shown there and doesn't need to be shown as an
+ // explicit prefix.
+ if haveMem {
+ if segIndex >= 0 {
+ inst.Prefix[segIndex] |= x86_PrefixImplicit
+ }
+ }
+
+ // Branch predict prefixes are overloaded segment prefixes,
+ // since segment prefixes don't make sense on conditional jumps.
+ // Rewrite final instance to prediction prefix.
+ // The set of instructions to which the prefixes apply (other then the
+ // Jcc conditional jumps) is not 100% clear from the manuals, but
+ // the disassemblers seem to agree about the LOOP and JCXZ instructions,
+ // so we'll follow along.
+ // TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+ if x86_isCondJmp[inst.Op] || x86_isLoop[inst.Op] || inst.Op == x86_JCXZ || inst.Op == x86_JECXZ || inst.Op == x86_JRCXZ {
+ PredictLoop:
+ for i := nprefix - 1; i >= 0; i-- {
+ p := inst.Prefix[i]
+ switch p & 0xFF {
+ case x86_PrefixCS:
+ inst.Prefix[i] = x86_PrefixPN
+ break PredictLoop
+ case x86_PrefixDS:
+ inst.Prefix[i] = x86_PrefixPT
+ break PredictLoop
+ }
+ }
+ }
+
+ // The BND prefix is part of the Intel Memory Protection Extensions (MPX).
+ // A REPN applied to certain control transfers is a BND prefix to bound
+ // the range of possible destinations. There's surprisingly little documentation
+ // about this, so we just do what libopcodes and xed agree on.
+ // In particular, it's unclear why a REPN applied to LOOP or JCXZ instructions
+ // does not turn into a BND.
+ // TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+ if x86_isCondJmp[inst.Op] || inst.Op == x86_JMP || inst.Op == x86_CALL || inst.Op == x86_RET {
+ for i := nprefix - 1; i >= 0; i-- {
+ p := inst.Prefix[i]
+ if p&^x86_PrefixIgnored == x86_PrefixREPN {
+ inst.Prefix[i] = x86_PrefixBND
+ break
+ }
+ }
+ }
+
+ // The LOCK prefix only applies to certain instructions, and then only
+ // to instances of the instruction with a memory destination.
+ // Other uses of LOCK are invalid and cause a processor exception,
+ // in contrast to the "just ignore it" spirit applied to all other prefixes.
+ // Mark invalid lock prefixes.
+ hasLock := false
+ if lockIndex >= 0 && inst.Prefix[lockIndex]&x86_PrefixImplicit == 0 {
+ switch inst.Op {
+ // TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+ case x86_ADD, x86_ADC, x86_AND, x86_BTC, x86_BTR, x86_BTS, x86_CMPXCHG, x86_CMPXCHG8B, x86_CMPXCHG16B, x86_DEC, x86_INC, x86_NEG, x86_NOT, x86_OR, x86_SBB, x86_SUB, x86_XOR, x86_XADD, x86_XCHG:
+ if x86_isMem(inst.Args[0]) {
+ hasLock = true
+ break
+ }
+ fallthrough
+ default:
+ inst.Prefix[lockIndex] |= x86_PrefixInvalid
+ }
+ }
+
+ // In certain cases, all of which require a memory destination,
+ // the REPN and REP prefixes are interpreted as XACQUIRE and XRELEASE
+ // from the Intel Transactional Synchroniation Extensions (TSX).
+ //
+ // The specific rules are:
+ // (1) Any instruction with a valid LOCK prefix can have XACQUIRE or XRELEASE.
+ // (2) Any XCHG, which always has an implicit LOCK, can have XACQUIRE or XRELEASE.
+ // (3) Any 0x88-, 0x89-, 0xC6-, or 0xC7-opcode MOV can have XRELEASE.
+ if x86_isMem(inst.Args[0]) {
+ if inst.Op == x86_XCHG {
+ hasLock = true
+ }
+
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ p := inst.Prefix[i] &^ x86_PrefixIgnored
+ switch p {
+ case x86_PrefixREPN:
+ if hasLock {
+ inst.Prefix[i] = inst.Prefix[i]&x86_PrefixIgnored | x86_PrefixXACQUIRE
+ }
+
+ case x86_PrefixREP:
+ if hasLock {
+ inst.Prefix[i] = inst.Prefix[i]&x86_PrefixIgnored | x86_PrefixXRELEASE
+ }
+
+ if inst.Op == x86_MOV {
+ op := (inst.Opcode >> 24) &^ 1
+ if op == 0x88 || op == 0xC6 {
+ inst.Prefix[i] = inst.Prefix[i]&x86_PrefixIgnored | x86_PrefixXRELEASE
+ }
+ }
+ }
+ }
+ }
+
+ // If REP is used on a non-REP-able instruction, mark the prefix as ignored.
+ if repIndex >= 0 {
+ switch inst.Prefix[repIndex] {
+ case x86_PrefixREP, x86_PrefixREPN:
+ switch inst.Op {
+ // According to the manuals, the REP/REPE prefix applies to all of these,
+ // while the REPN applies only to some of them. However, both libopcodes
+ // and xed show both prefixes explicitly for all instructions, so we do the same.
+ // TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+ case x86_INSB, x86_INSW, x86_INSD,
+ x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ,
+ x86_OUTSB, x86_OUTSW, x86_OUTSD,
+ x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ,
+ x86_CMPSB, x86_CMPSW, x86_CMPSD, x86_CMPSQ,
+ x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ,
+ x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ:
+ // ok
+ default:
+ inst.Prefix[repIndex] |= x86_PrefixIgnored
+ }
+ }
+ }
+
+ // If REX was present, mark implicit if all the 1 bits were consumed.
+ if rexIndex >= 0 {
+ if rexUsed != 0 {
+ rexUsed |= x86_PrefixREX
+ }
+ if rex&^rexUsed == 0 {
+ inst.Prefix[rexIndex] |= x86_PrefixImplicit
+ }
+ }
+
+ inst.DataSize = dataMode
+ inst.AddrSize = addrMode
+ inst.Mode = mode
+ inst.Len = pos
+ return inst, nil
+}
+
+var x86_errInternal = errors.New("internal error")
+
+// addr16 records the eight 16-bit addressing modes.
+var x86_addr16 = [8]x86_Mem{
+ {Base: x86_BX, Scale: 1, Index: x86_SI},
+ {Base: x86_BX, Scale: 1, Index: x86_DI},
+ {Base: x86_BP, Scale: 1, Index: x86_SI},
+ {Base: x86_BP, Scale: 1, Index: x86_DI},
+ {Base: x86_SI},
+ {Base: x86_DI},
+ {Base: x86_BP},
+ {Base: x86_BX},
+}
+
+// baseReg returns the base register for a given register size in bits.
+func x86_baseRegForBits(bits int) x86_Reg {
+ switch bits {
+ case 8:
+ return x86_AL
+ case 16:
+ return x86_AX
+ case 32:
+ return x86_EAX
+ case 64:
+ return x86_RAX
+ }
+ return 0
+}
+
+// baseReg records the base register for argument types that specify
+// a range of registers indexed by op, regop, or rm.
+var x86_baseReg = [...]x86_Reg{
+ x86_xArgDR0dashDR7: x86_DR0,
+ x86_xArgMm1: x86_M0,
+ x86_xArgMm2: x86_M0,
+ x86_xArgMm2M64: x86_M0,
+ x86_xArgMm: x86_M0,
+ x86_xArgMmM32: x86_M0,
+ x86_xArgMmM64: x86_M0,
+ x86_xArgR16: x86_AX,
+ x86_xArgR16op: x86_AX,
+ x86_xArgR32: x86_EAX,
+ x86_xArgR32M16: x86_EAX,
+ x86_xArgR32M8: x86_EAX,
+ x86_xArgR32op: x86_EAX,
+ x86_xArgR64: x86_RAX,
+ x86_xArgR64M16: x86_RAX,
+ x86_xArgR64op: x86_RAX,
+ x86_xArgR8: x86_AL,
+ x86_xArgR8op: x86_AL,
+ x86_xArgRM16: x86_AX,
+ x86_xArgRM32: x86_EAX,
+ x86_xArgRM64: x86_RAX,
+ x86_xArgRM8: x86_AL,
+ x86_xArgRmf16: x86_AX,
+ x86_xArgRmf32: x86_EAX,
+ x86_xArgRmf64: x86_RAX,
+ x86_xArgSTi: x86_F0,
+ x86_xArgTR0dashTR7: x86_TR0,
+ x86_xArgXmm1: x86_X0,
+ x86_xArgXmm2: x86_X0,
+ x86_xArgXmm2M128: x86_X0,
+ x86_xArgXmm2M16: x86_X0,
+ x86_xArgXmm2M32: x86_X0,
+ x86_xArgXmm2M64: x86_X0,
+ x86_xArgXmm: x86_X0,
+ x86_xArgXmmM128: x86_X0,
+ x86_xArgXmmM32: x86_X0,
+ x86_xArgXmmM64: x86_X0,
+}
+
+// prefixToSegment returns the segment register
+// corresponding to a particular segment prefix.
+func x86_prefixToSegment(p x86_Prefix) x86_Reg {
+ switch p &^ x86_PrefixImplicit {
+ case x86_PrefixCS:
+ return x86_CS
+ case x86_PrefixDS:
+ return x86_DS
+ case x86_PrefixES:
+ return x86_ES
+ case x86_PrefixFS:
+ return x86_FS
+ case x86_PrefixGS:
+ return x86_GS
+ case x86_PrefixSS:
+ return x86_SS
+ }
+ return 0
+}
+
+// fixedArg records the fixed arguments corresponding to the given bytecodes.
+var x86_fixedArg = [...]x86_Arg{
+ x86_xArg1: x86_Imm(1),
+ x86_xArg3: x86_Imm(3),
+ x86_xArgAL: x86_AL,
+ x86_xArgAX: x86_AX,
+ x86_xArgDX: x86_DX,
+ x86_xArgEAX: x86_EAX,
+ x86_xArgEDX: x86_EDX,
+ x86_xArgRAX: x86_RAX,
+ x86_xArgRDX: x86_RDX,
+ x86_xArgCL: x86_CL,
+ x86_xArgCS: x86_CS,
+ x86_xArgDS: x86_DS,
+ x86_xArgES: x86_ES,
+ x86_xArgFS: x86_FS,
+ x86_xArgGS: x86_GS,
+ x86_xArgSS: x86_SS,
+ x86_xArgST: x86_F0,
+ x86_xArgXMM0: x86_X0,
+}
+
+// memBytes records the size of the memory pointed at
+// by a memory argument of the given form.
+var x86_memBytes = [...]int8{
+ x86_xArgM128: 128 / 8,
+ x86_xArgM16: 16 / 8,
+ x86_xArgM16and16: (16 + 16) / 8,
+ x86_xArgM16colon16: (16 + 16) / 8,
+ x86_xArgM16colon32: (16 + 32) / 8,
+ x86_xArgM16int: 16 / 8,
+ x86_xArgM2byte: 2,
+ x86_xArgM32: 32 / 8,
+ x86_xArgM32and32: (32 + 32) / 8,
+ x86_xArgM32fp: 32 / 8,
+ x86_xArgM32int: 32 / 8,
+ x86_xArgM64: 64 / 8,
+ x86_xArgM64fp: 64 / 8,
+ x86_xArgM64int: 64 / 8,
+ x86_xArgMm2M64: 64 / 8,
+ x86_xArgMmM32: 32 / 8,
+ x86_xArgMmM64: 64 / 8,
+ x86_xArgMoffs16: 16 / 8,
+ x86_xArgMoffs32: 32 / 8,
+ x86_xArgMoffs64: 64 / 8,
+ x86_xArgMoffs8: 8 / 8,
+ x86_xArgR32M16: 16 / 8,
+ x86_xArgR32M8: 8 / 8,
+ x86_xArgR64M16: 16 / 8,
+ x86_xArgRM16: 16 / 8,
+ x86_xArgRM32: 32 / 8,
+ x86_xArgRM64: 64 / 8,
+ x86_xArgRM8: 8 / 8,
+ x86_xArgXmm2M128: 128 / 8,
+ x86_xArgXmm2M16: 16 / 8,
+ x86_xArgXmm2M32: 32 / 8,
+ x86_xArgXmm2M64: 64 / 8,
+ x86_xArgXmm: 128 / 8,
+ x86_xArgXmmM128: 128 / 8,
+ x86_xArgXmmM32: 32 / 8,
+ x86_xArgXmmM64: 64 / 8,
+}
+
+// isCondJmp records the conditional jumps.
+var x86_isCondJmp = [x86_maxOp + 1]bool{
+ x86_JA: true,
+ x86_JAE: true,
+ x86_JB: true,
+ x86_JBE: true,
+ x86_JE: true,
+ x86_JG: true,
+ x86_JGE: true,
+ x86_JL: true,
+ x86_JLE: true,
+ x86_JNE: true,
+ x86_JNO: true,
+ x86_JNP: true,
+ x86_JNS: true,
+ x86_JO: true,
+ x86_JP: true,
+ x86_JS: true,
+}
+
+// isLoop records the loop operators.
+var x86_isLoop = [x86_maxOp + 1]bool{
+ x86_LOOP: true,
+ x86_LOOPE: true,
+ x86_LOOPNE: true,
+ x86_JECXZ: true,
+ x86_JRCXZ: true,
+}
+
+/* gnu.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
+// This general form is often called ``AT&T syntax'' as a reference to AT&T System V Unix.
+func x86_GNUSyntax(inst x86_Inst) string {
+ // Rewrite instruction to mimic GNU peculiarities.
+ // Note that inst has been passed by value and contains
+ // no pointers, so any changes we make here are local
+ // and will not propagate back out to the caller.
+
+ // Adjust opcode [sic].
+ switch inst.Op {
+ case x86_FDIV, x86_FDIVR, x86_FSUB, x86_FSUBR, x86_FDIVP, x86_FDIVRP, x86_FSUBP, x86_FSUBRP:
+ // DC E0, DC F0: libopcodes swaps FSUBR/FSUB and FDIVR/FDIV, at least
+ // if you believe the Intel manual is correct (the encoding is irregular as given;
+ // libopcodes uses the more regular expected encoding).
+ // TODO(rsc): Test to ensure Intel manuals are correct and report to libopcodes maintainers?
+ // NOTE: iant thinks this is deliberate, but we can't find the history.
+ _, reg1 := inst.Args[0].(x86_Reg)
+ _, reg2 := inst.Args[1].(x86_Reg)
+ if reg1 && reg2 && (inst.Opcode>>24 == 0xDC || inst.Opcode>>24 == 0xDE) {
+ switch inst.Op {
+ case x86_FDIV:
+ inst.Op = x86_FDIVR
+ case x86_FDIVR:
+ inst.Op = x86_FDIV
+ case x86_FSUB:
+ inst.Op = x86_FSUBR
+ case x86_FSUBR:
+ inst.Op = x86_FSUB
+ case x86_FDIVP:
+ inst.Op = x86_FDIVRP
+ case x86_FDIVRP:
+ inst.Op = x86_FDIVP
+ case x86_FSUBP:
+ inst.Op = x86_FSUBRP
+ case x86_FSUBRP:
+ inst.Op = x86_FSUBP
+ }
+ }
+
+ case x86_MOVNTSD:
+ // MOVNTSD is F2 0F 2B /r.
+ // MOVNTSS is F3 0F 2B /r (supposedly; not in manuals).
+ // Usually inner prefixes win for display,
+ // so that F3 F2 0F 2B 11 is REP MOVNTSD
+ // and F2 F3 0F 2B 11 is REPN MOVNTSS.
+ // Libopcodes always prefers MOVNTSS regardless of prefix order.
+ if x86_countPrefix(&inst, 0xF3) > 0 {
+ found := false
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ switch inst.Prefix[i] & 0xFF {
+ case 0xF3:
+ if !found {
+ found = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ case 0xF2:
+ inst.Prefix[i] &^= x86_PrefixImplicit
+ }
+ }
+ inst.Op = x86_MOVNTSS
+ }
+ }
+
+ // Add implicit arguments.
+ switch inst.Op {
+ case x86_MONITOR:
+ inst.Args[0] = x86_EDX
+ inst.Args[1] = x86_ECX
+ inst.Args[2] = x86_EAX
+ if inst.AddrSize == 16 {
+ inst.Args[2] = x86_AX
+ }
+
+ case x86_MWAIT:
+ if inst.Mode == 64 {
+ inst.Args[0] = x86_RCX
+ inst.Args[1] = x86_RAX
+ } else {
+ inst.Args[0] = x86_ECX
+ inst.Args[1] = x86_EAX
+ }
+ }
+
+ // Adjust which prefixes will be displayed.
+ // The rule is to display all the prefixes not implied by
+ // the usual instruction display, that is, all the prefixes
+ // except the ones with PrefixImplicit set.
+ // However, of course, there are exceptions to the rule.
+ switch inst.Op {
+ case x86_CRC32:
+ // CRC32 has a mandatory F2 prefix.
+ // If there are multiple F2s and no F3s, the extra F2s do not print.
+ // (And Decode has already marked them implicit.)
+ // However, if there is an F3 anywhere, then the extra F2s do print.
+ // If there are multiple F2 prefixes *and* an (ignored) F3,
+ // then libopcodes prints the extra F2s as REPNs.
+ if x86_countPrefix(&inst, 0xF2) > 1 {
+ x86_unmarkImplicit(&inst, 0xF2)
+ x86_markLastImplicit(&inst, 0xF2)
+ }
+
+ // An unused data size override should probably be shown,
+ // to distinguish DATA16 CRC32B from plain CRC32B,
+ // but libopcodes always treats the final override as implicit
+ // and the others as explicit.
+ x86_unmarkImplicit(&inst, x86_PrefixDataSize)
+ x86_markLastImplicit(&inst, x86_PrefixDataSize)
+
+ case x86_CVTSI2SD, x86_CVTSI2SS:
+ if !x86_isMem(inst.Args[1]) {
+ x86_markLastImplicit(&inst, x86_PrefixDataSize)
+ }
+
+ case x86_CVTSD2SI, x86_CVTSS2SI, x86_CVTTSD2SI, x86_CVTTSS2SI,
+ x86_ENTER, x86_FLDENV, x86_FNSAVE, x86_FNSTENV, x86_FRSTOR, x86_LGDT, x86_LIDT, x86_LRET,
+ x86_POP, x86_PUSH, x86_RET, x86_SGDT, x86_SIDT, x86_SYSRET, x86_XBEGIN:
+ x86_markLastImplicit(&inst, x86_PrefixDataSize)
+
+ case x86_LOOP, x86_LOOPE, x86_LOOPNE, x86_MONITOR:
+ x86_markLastImplicit(&inst, x86_PrefixAddrSize)
+
+ case x86_MOV:
+ // The 16-bit and 32-bit forms of MOV Sreg, dst and MOV src, Sreg
+ // cannot be distinguished when src or dst refers to memory, because
+ // Sreg is always a 16-bit value, even when we're doing a 32-bit
+ // instruction. Because the instruction tables distinguished these two,
+ // any operand size prefix has been marked as used (to decide which
+ // branch to take). Unmark it, so that it will show up in disassembly,
+ // so that the reader can tell the size of memory operand.
+ // up with the same arguments
+ dst, _ := inst.Args[0].(x86_Reg)
+ src, _ := inst.Args[1].(x86_Reg)
+ if x86_ES <= src && src <= x86_GS && x86_isMem(inst.Args[0]) || x86_ES <= dst && dst <= x86_GS && x86_isMem(inst.Args[1]) {
+ x86_unmarkImplicit(&inst, x86_PrefixDataSize)
+ }
+
+ case x86_MOVDQU:
+ if x86_countPrefix(&inst, 0xF3) > 1 {
+ x86_unmarkImplicit(&inst, 0xF3)
+ x86_markLastImplicit(&inst, 0xF3)
+ }
+
+ case x86_MOVQ2DQ:
+ x86_markLastImplicit(&inst, x86_PrefixDataSize)
+
+ case x86_SLDT, x86_SMSW, x86_STR, x86_FXRSTOR, x86_XRSTOR, x86_XSAVE, x86_XSAVEOPT, x86_CMPXCHG8B:
+ if x86_isMem(inst.Args[0]) {
+ x86_unmarkImplicit(&inst, x86_PrefixDataSize)
+ }
+
+ case x86_SYSEXIT:
+ x86_unmarkImplicit(&inst, x86_PrefixDataSize)
+ }
+
+ if x86_isCondJmp[inst.Op] || x86_isLoop[inst.Op] || inst.Op == x86_JCXZ || inst.Op == x86_JECXZ || inst.Op == x86_JRCXZ {
+ if x86_countPrefix(&inst, x86_PrefixCS) > 0 && x86_countPrefix(&inst, x86_PrefixDS) > 0 {
+ for i, p := range inst.Prefix {
+ switch p & 0xFFF {
+ case x86_PrefixPN, x86_PrefixPT:
+ inst.Prefix[i] &= 0xF0FF // cut interpretation bits, producing original segment prefix
+ }
+ }
+ }
+ }
+
+ // XACQUIRE/XRELEASE adjustment.
+ if inst.Op == x86_MOV {
+ // MOV into memory is a candidate for turning REP into XRELEASE.
+ // However, if the REP is followed by a REPN, that REPN blocks the
+ // conversion.
+ haveREPN := false
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ switch inst.Prefix[i] &^ x86_PrefixIgnored {
+ case x86_PrefixREPN:
+ haveREPN = true
+ case x86_PrefixXRELEASE:
+ if haveREPN {
+ inst.Prefix[i] = x86_PrefixREP
+ }
+ }
+ }
+ }
+
+ // We only format the final F2/F3 as XRELEASE/XACQUIRE.
+ haveXA := false
+ haveXR := false
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ switch inst.Prefix[i] &^ x86_PrefixIgnored {
+ case x86_PrefixXRELEASE:
+ if !haveXR {
+ haveXR = true
+ } else {
+ inst.Prefix[i] = x86_PrefixREP
+ }
+
+ case x86_PrefixXACQUIRE:
+ if !haveXA {
+ haveXA = true
+ } else {
+ inst.Prefix[i] = x86_PrefixREPN
+ }
+ }
+ }
+
+ // Determine opcode.
+ op := strings.ToLower(inst.Op.String())
+ if alt := x86_gnuOp[inst.Op]; alt != "" {
+ op = alt
+ }
+
+ // Determine opcode suffix.
+ // Libopcodes omits the suffix if the width of the operation
+ // can be inferred from a register arguments. For example,
+ // add $1, %ebx has no suffix because you can tell from the
+ // 32-bit register destination that it is a 32-bit add,
+ // but in addl $1, (%ebx), the destination is memory, so the
+ // size is not evident without the l suffix.
+ needSuffix := true
+SuffixLoop:
+ for i, a := range inst.Args {
+ if a == nil {
+ break
+ }
+ switch a := a.(type) {
+ case x86_Reg:
+ switch inst.Op {
+ case x86_MOVSX, x86_MOVZX:
+ continue
+
+ case x86_SHL, x86_SHR, x86_RCL, x86_RCR, x86_ROL, x86_ROR, x86_SAR:
+ if i == 1 {
+ // shift count does not tell us operand size
+ continue
+ }
+
+ case x86_CRC32:
+ // The source argument does tell us operand size,
+ // but libopcodes still always puts a suffix on crc32.
+ continue
+
+ case x86_PUSH, x86_POP:
+ // Even though segment registers are 16-bit, push and pop
+ // can save/restore them from 32-bit slots, so they
+ // do not imply operand size.
+ if x86_ES <= a && a <= x86_GS {
+ continue
+ }
+
+ case x86_CVTSI2SD, x86_CVTSI2SS:
+ // The integer register argument takes priority.
+ if x86_X0 <= a && a <= x86_X15 {
+ continue
+ }
+ }
+
+ if x86_AL <= a && a <= x86_R15 || x86_ES <= a && a <= x86_GS || x86_X0 <= a && a <= x86_X15 || x86_M0 <= a && a <= x86_M7 {
+ needSuffix = false
+ break SuffixLoop
+ }
+ }
+ }
+
+ if needSuffix {
+ switch inst.Op {
+ case x86_CMPXCHG8B, x86_FLDCW, x86_FNSTCW, x86_FNSTSW, x86_LDMXCSR, x86_LLDT, x86_LMSW, x86_LTR, x86_PCLMULQDQ,
+ x86_SETA, x86_SETAE, x86_SETB, x86_SETBE, x86_SETE, x86_SETG, x86_SETGE, x86_SETL, x86_SETLE, x86_SETNE, x86_SETNO, x86_SETNP, x86_SETNS, x86_SETO, x86_SETP, x86_SETS,
+ x86_SLDT, x86_SMSW, x86_STMXCSR, x86_STR, x86_VERR, x86_VERW:
+ // For various reasons, libopcodes emits no suffix for these instructions.
+
+ case x86_CRC32:
+ op += x86_byteSizeSuffix(x86_argBytes(&inst, inst.Args[1]))
+
+ case x86_LGDT, x86_LIDT, x86_SGDT, x86_SIDT:
+ op += x86_byteSizeSuffix(inst.DataSize / 8)
+
+ case x86_MOVZX, x86_MOVSX:
+ // Integer size conversions get two suffixes.
+ op = op[:4] + x86_byteSizeSuffix(x86_argBytes(&inst, inst.Args[1])) + x86_byteSizeSuffix(x86_argBytes(&inst, inst.Args[0]))
+
+ case x86_LOOP, x86_LOOPE, x86_LOOPNE:
+ // Add w suffix to indicate use of CX register instead of ECX.
+ if inst.AddrSize == 16 {
+ op += "w"
+ }
+
+ case x86_CALL, x86_ENTER, x86_JMP, x86_LCALL, x86_LEAVE, x86_LJMP, x86_LRET, x86_RET, x86_SYSRET, x86_XBEGIN:
+ // Add w suffix to indicate use of 16-bit target.
+ // Exclude JMP rel8.
+ if inst.Opcode>>24 == 0xEB {
+ break
+ }
+ if inst.DataSize == 16 && inst.Mode != 16 {
+ x86_markLastImplicit(&inst, x86_PrefixDataSize)
+ op += "w"
+ } else if inst.Mode == 64 {
+ op += "q"
+ }
+
+ case x86_FRSTOR, x86_FNSAVE, x86_FNSTENV, x86_FLDENV:
+ // Add s suffix to indicate shortened FPU state (I guess).
+ if inst.DataSize == 16 {
+ op += "s"
+ }
+
+ case x86_PUSH, x86_POP:
+ if x86_markLastImplicit(&inst, x86_PrefixDataSize) {
+ op += x86_byteSizeSuffix(inst.DataSize / 8)
+ } else if inst.Mode == 64 {
+ op += "q"
+ } else {
+ op += x86_byteSizeSuffix(inst.MemBytes)
+ }
+
+ default:
+ if x86_isFloat(inst.Op) {
+ // I can't explain any of this, but it's what libopcodes does.
+ switch inst.MemBytes {
+ default:
+ if (inst.Op == x86_FLD || inst.Op == x86_FSTP) && x86_isMem(inst.Args[0]) {
+ op += "t"
+ }
+ case 4:
+ if x86_isFloatInt(inst.Op) {
+ op += "l"
+ } else {
+ op += "s"
+ }
+ case 8:
+ if x86_isFloatInt(inst.Op) {
+ op += "ll"
+ } else {
+ op += "l"
+ }
+ }
+ break
+ }
+
+ op += x86_byteSizeSuffix(inst.MemBytes)
+ }
+ }
+
+ // Adjust special case opcodes.
+ switch inst.Op {
+ case 0:
+ if inst.Prefix[0] != 0 {
+ return strings.ToLower(inst.Prefix[0].String())
+ }
+
+ case x86_INT:
+ if inst.Opcode>>24 == 0xCC {
+ inst.Args[0] = nil
+ op = "int3"
+ }
+
+ case x86_CMPPS, x86_CMPPD, x86_CMPSD_XMM, x86_CMPSS:
+ imm, ok := inst.Args[2].(x86_Imm)
+ if ok && 0 <= imm && imm < 8 {
+ inst.Args[2] = nil
+ op = x86_cmppsOps[imm] + op[3:]
+ }
+
+ case x86_PCLMULQDQ:
+ imm, ok := inst.Args[2].(x86_Imm)
+ if ok && imm&^0x11 == 0 {
+ inst.Args[2] = nil
+ op = x86_pclmulqOps[(imm&0x10)>>3|(imm&1)]
+ }
+
+ case x86_XLATB:
+ if x86_markLastImplicit(&inst, x86_PrefixAddrSize) {
+ op = "xlat" // not xlatb
+ }
+ }
+
+ // Build list of argument strings.
+ var (
+ usedPrefixes bool // segment prefixes consumed by Mem formatting
+ args []string // formatted arguments
+ )
+ for i, a := range inst.Args {
+ if a == nil {
+ break
+ }
+ switch inst.Op {
+ case x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ, x86_OUTSB, x86_OUTSW, x86_OUTSD:
+ if i == 0 {
+ usedPrefixes = true // disable use of prefixes for first argument
+ } else {
+ usedPrefixes = false
+ }
+ }
+ if a == x86_Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
+ continue
+ }
+ args = append(args, x86_gnuArg(&inst, a, &usedPrefixes))
+ }
+
+ // The default is to print the arguments in reverse Intel order.
+ // A few instructions inhibit this behavior.
+ switch inst.Op {
+ case x86_BOUND, x86_LCALL, x86_ENTER, x86_LJMP:
+ // no reverse
+ default:
+ // reverse args
+ for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+ args[i], args[j] = args[j], args[i]
+ }
+ }
+
+ // Build prefix string.
+ // Must be after argument formatting, which can turn off segment prefixes.
+ var (
+ prefix = "" // output string
+ numAddr = 0
+ numData = 0
+ implicitData = false
+ )
+ for _, p := range inst.Prefix {
+ if p&0xFF == x86_PrefixDataSize && p&x86_PrefixImplicit != 0 {
+ implicitData = true
+ }
+ }
+ for _, p := range inst.Prefix {
+ if p == 0 {
+ break
+ }
+ if p&x86_PrefixImplicit != 0 {
+ continue
+ }
+ switch p &^ (x86_PrefixIgnored | x86_PrefixInvalid) {
+ default:
+ if p.IsREX() {
+ if p&0xFF == x86_PrefixREX {
+ prefix += "rex "
+ } else {
+ prefix += "rex." + p.String()[4:] + " "
+ }
+ break
+ }
+ prefix += strings.ToLower(p.String()) + " "
+
+ case x86_PrefixPN:
+ op += ",pn"
+ continue
+
+ case x86_PrefixPT:
+ op += ",pt"
+ continue
+
+ case x86_PrefixAddrSize, x86_PrefixAddr16, x86_PrefixAddr32:
+ // For unknown reasons, if the addr16 prefix is repeated,
+ // libopcodes displays all but the last as addr32, even though
+ // the addressing form used in a memory reference is clearly
+ // still 16-bit.
+ n := 32
+ if inst.Mode == 32 {
+ n = 16
+ }
+ numAddr++
+ if x86_countPrefix(&inst, x86_PrefixAddrSize) > numAddr {
+ n = inst.Mode
+ }
+ prefix += fmt.Sprintf("addr%d ", n)
+ continue
+
+ case x86_PrefixData16, x86_PrefixData32:
+ if implicitData && x86_countPrefix(&inst, x86_PrefixDataSize) > 1 {
+ // Similar to the addr32 logic above, but it only kicks in
+ // when something used the data size prefix (one is implicit).
+ n := 16
+ if inst.Mode == 16 {
+ n = 32
+ }
+ numData++
+ if x86_countPrefix(&inst, x86_PrefixDataSize) > numData {
+ if inst.Mode == 16 {
+ n = 16
+ } else {
+ n = 32
+ }
+ }
+ prefix += fmt.Sprintf("data%d ", n)
+ continue
+ }
+ prefix += strings.ToLower(p.String()) + " "
+ }
+ }
+
+ // Finally! Put it all together.
+ text := prefix + op
+ if args != nil {
+ text += " "
+ // Indirect call/jmp gets a star to distinguish from direct jump address.
+ if (inst.Op == x86_CALL || inst.Op == x86_JMP || inst.Op == x86_LJMP || inst.Op == x86_LCALL) && (x86_isMem(inst.Args[0]) || x86_isReg(inst.Args[0])) {
+ text += "*"
+ }
+ text += strings.Join(args, ",")
+ }
+ return text
+}
+
+// gnuArg returns the GNU syntax for the argument x from the instruction inst.
+// If *usedPrefixes is false and x is a Mem, then the formatting
+// includes any segment prefixes and sets *usedPrefixes to true.
+func x86_gnuArg(inst *x86_Inst, x x86_Arg, usedPrefixes *bool) string {
+ if x == nil {
+ return "<nil>"
+ }
+ switch x := x.(type) {
+ case x86_Reg:
+ switch inst.Op {
+ case x86_CVTSI2SS, x86_CVTSI2SD, x86_CVTSS2SI, x86_CVTSD2SI, x86_CVTTSD2SI, x86_CVTTSS2SI:
+ if inst.DataSize == 16 && x86_EAX <= x && x <= x86_R15L {
+ x -= x86_EAX - x86_AX
+ }
+
+ case x86_IN, x86_INSB, x86_INSW, x86_INSD, x86_OUT, x86_OUTSB, x86_OUTSW, x86_OUTSD:
+ // DX is the port, but libopcodes prints it as if it were a memory reference.
+ if x == x86_DX {
+ return "(%dx)"
+ }
+ }
+ return x86_gccRegName[x]
+ case x86_Mem:
+ seg := ""
+ var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
+ switch x.Segment {
+ case x86_CS:
+ haveCS = true
+ case x86_DS:
+ haveDS = true
+ case x86_ES:
+ haveES = true
+ case x86_FS:
+ haveFS = true
+ case x86_GS:
+ haveGS = true
+ case x86_SS:
+ haveSS = true
+ }
+ switch inst.Op {
+ case x86_INSB, x86_INSW, x86_INSD, x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ, x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ:
+ // These do not accept segment prefixes, at least in the GNU rendering.
+ default:
+ if *usedPrefixes {
+ break
+ }
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ p := inst.Prefix[i] &^ x86_PrefixIgnored
+ if p == 0 {
+ continue
+ }
+ switch p {
+ case x86_PrefixCS:
+ if !haveCS {
+ haveCS = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ case x86_PrefixDS:
+ if !haveDS {
+ haveDS = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ case x86_PrefixES:
+ if !haveES {
+ haveES = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ case x86_PrefixFS:
+ if !haveFS {
+ haveFS = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ case x86_PrefixGS:
+ if !haveGS {
+ haveGS = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ case x86_PrefixSS:
+ if !haveSS {
+ haveSS = true
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ }
+ }
+ *usedPrefixes = true
+ }
+ if haveCS {
+ seg += "%cs:"
+ }
+ if haveDS {
+ seg += "%ds:"
+ }
+ if haveSS {
+ seg += "%ss:"
+ }
+ if haveES {
+ seg += "%es:"
+ }
+ if haveFS {
+ seg += "%fs:"
+ }
+ if haveGS {
+ seg += "%gs:"
+ }
+ disp := ""
+ if x.Disp != 0 {
+ disp = fmt.Sprintf("%#x", x.Disp)
+ }
+ if x.Scale == 0 || x.Index == 0 && x.Scale == 1 && (x.Base == x86_ESP || x.Base == x86_RSP || x.Base == 0 && inst.Mode == 64) {
+ if x.Base == 0 {
+ return seg + disp
+ }
+ return fmt.Sprintf("%s%s(%s)", seg, disp, x86_gccRegName[x.Base])
+ }
+ base := x86_gccRegName[x.Base]
+ if x.Base == 0 {
+ base = ""
+ }
+ index := x86_gccRegName[x.Index]
+ if x.Index == 0 {
+ if inst.AddrSize == 64 {
+ index = "%riz"
+ } else {
+ index = "%eiz"
+ }
+ }
+ if x86_AX <= x.Base && x.Base <= x86_DI {
+ // 16-bit addressing - no scale
+ return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
+ }
+ return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
+ case x86_Rel:
+ return fmt.Sprintf(".%+#x", int32(x))
+ case x86_Imm:
+ if inst.Mode == 32 {
+ return fmt.Sprintf("$%#x", uint32(x))
+ }
+ return fmt.Sprintf("$%#x", int64(x))
+ }
+ return x.String()
+}
+
+var x86_gccRegName = [...]string{
+ 0: "REG0",
+ x86_AL: "%al",
+ x86_CL: "%cl",
+ x86_BL: "%bl",
+ x86_DL: "%dl",
+ x86_AH: "%ah",
+ x86_CH: "%ch",
+ x86_BH: "%bh",
+ x86_DH: "%dh",
+ x86_SPB: "%spl",
+ x86_BPB: "%bpl",
+ x86_SIB: "%sil",
+ x86_DIB: "%dil",
+ x86_R8B: "%r8b",
+ x86_R9B: "%r9b",
+ x86_R10B: "%r10b",
+ x86_R11B: "%r11b",
+ x86_R12B: "%r12b",
+ x86_R13B: "%r13b",
+ x86_R14B: "%r14b",
+ x86_R15B: "%r15b",
+ x86_AX: "%ax",
+ x86_CX: "%cx",
+ x86_BX: "%bx",
+ x86_DX: "%dx",
+ x86_SP: "%sp",
+ x86_BP: "%bp",
+ x86_SI: "%si",
+ x86_DI: "%di",
+ x86_R8W: "%r8w",
+ x86_R9W: "%r9w",
+ x86_R10W: "%r10w",
+ x86_R11W: "%r11w",
+ x86_R12W: "%r12w",
+ x86_R13W: "%r13w",
+ x86_R14W: "%r14w",
+ x86_R15W: "%r15w",
+ x86_EAX: "%eax",
+ x86_ECX: "%ecx",
+ x86_EDX: "%edx",
+ x86_EBX: "%ebx",
+ x86_ESP: "%esp",
+ x86_EBP: "%ebp",
+ x86_ESI: "%esi",
+ x86_EDI: "%edi",
+ x86_R8L: "%r8d",
+ x86_R9L: "%r9d",
+ x86_R10L: "%r10d",
+ x86_R11L: "%r11d",
+ x86_R12L: "%r12d",
+ x86_R13L: "%r13d",
+ x86_R14L: "%r14d",
+ x86_R15L: "%r15d",
+ x86_RAX: "%rax",
+ x86_RCX: "%rcx",
+ x86_RDX: "%rdx",
+ x86_RBX: "%rbx",
+ x86_RSP: "%rsp",
+ x86_RBP: "%rbp",
+ x86_RSI: "%rsi",
+ x86_RDI: "%rdi",
+ x86_R8: "%r8",
+ x86_R9: "%r9",
+ x86_R10: "%r10",
+ x86_R11: "%r11",
+ x86_R12: "%r12",
+ x86_R13: "%r13",
+ x86_R14: "%r14",
+ x86_R15: "%r15",
+ x86_IP: "%ip",
+ x86_EIP: "%eip",
+ x86_RIP: "%rip",
+ x86_F0: "%st",
+ x86_F1: "%st(1)",
+ x86_F2: "%st(2)",
+ x86_F3: "%st(3)",
+ x86_F4: "%st(4)",
+ x86_F5: "%st(5)",
+ x86_F6: "%st(6)",
+ x86_F7: "%st(7)",
+ x86_M0: "%mm0",
+ x86_M1: "%mm1",
+ x86_M2: "%mm2",
+ x86_M3: "%mm3",
+ x86_M4: "%mm4",
+ x86_M5: "%mm5",
+ x86_M6: "%mm6",
+ x86_M7: "%mm7",
+ x86_X0: "%xmm0",
+ x86_X1: "%xmm1",
+ x86_X2: "%xmm2",
+ x86_X3: "%xmm3",
+ x86_X4: "%xmm4",
+ x86_X5: "%xmm5",
+ x86_X6: "%xmm6",
+ x86_X7: "%xmm7",
+ x86_X8: "%xmm8",
+ x86_X9: "%xmm9",
+ x86_X10: "%xmm10",
+ x86_X11: "%xmm11",
+ x86_X12: "%xmm12",
+ x86_X13: "%xmm13",
+ x86_X14: "%xmm14",
+ x86_X15: "%xmm15",
+ x86_CS: "%cs",
+ x86_SS: "%ss",
+ x86_DS: "%ds",
+ x86_ES: "%es",
+ x86_FS: "%fs",
+ x86_GS: "%gs",
+ x86_GDTR: "%gdtr",
+ x86_IDTR: "%idtr",
+ x86_LDTR: "%ldtr",
+ x86_MSW: "%msw",
+ x86_TASK: "%task",
+ x86_CR0: "%cr0",
+ x86_CR1: "%cr1",
+ x86_CR2: "%cr2",
+ x86_CR3: "%cr3",
+ x86_CR4: "%cr4",
+ x86_CR5: "%cr5",
+ x86_CR6: "%cr6",
+ x86_CR7: "%cr7",
+ x86_CR8: "%cr8",
+ x86_CR9: "%cr9",
+ x86_CR10: "%cr10",
+ x86_CR11: "%cr11",
+ x86_CR12: "%cr12",
+ x86_CR13: "%cr13",
+ x86_CR14: "%cr14",
+ x86_CR15: "%cr15",
+ x86_DR0: "%db0",
+ x86_DR1: "%db1",
+ x86_DR2: "%db2",
+ x86_DR3: "%db3",
+ x86_DR4: "%db4",
+ x86_DR5: "%db5",
+ x86_DR6: "%db6",
+ x86_DR7: "%db7",
+ x86_TR0: "%tr0",
+ x86_TR1: "%tr1",
+ x86_TR2: "%tr2",
+ x86_TR3: "%tr3",
+ x86_TR4: "%tr4",
+ x86_TR5: "%tr5",
+ x86_TR6: "%tr6",
+ x86_TR7: "%tr7",
+}
+
+var x86_gnuOp = map[x86_Op]string{
+ x86_CBW: "cbtw",
+ x86_CDQ: "cltd",
+ x86_CMPSD: "cmpsl",
+ x86_CMPSD_XMM: "cmpsd",
+ x86_CWD: "cwtd",
+ x86_CWDE: "cwtl",
+ x86_CQO: "cqto",
+ x86_INSD: "insl",
+ x86_IRET: "iretw",
+ x86_IRETD: "iret",
+ x86_IRETQ: "iretq",
+ x86_LODSB: "lods",
+ x86_LODSD: "lods",
+ x86_LODSQ: "lods",
+ x86_LODSW: "lods",
+ x86_MOVSD: "movsl",
+ x86_MOVSD_XMM: "movsd",
+ x86_OUTSD: "outsl",
+ x86_POPA: "popaw",
+ x86_POPAD: "popa",
+ x86_POPF: "popfw",
+ x86_POPFD: "popf",
+ x86_PUSHA: "pushaw",
+ x86_PUSHAD: "pusha",
+ x86_PUSHF: "pushfw",
+ x86_PUSHFD: "pushf",
+ x86_SCASB: "scas",
+ x86_SCASD: "scas",
+ x86_SCASQ: "scas",
+ x86_SCASW: "scas",
+ x86_STOSB: "stos",
+ x86_STOSD: "stos",
+ x86_STOSQ: "stos",
+ x86_STOSW: "stos",
+ x86_XLATB: "xlat",
+}
+
+var x86_cmppsOps = []string{
+ "cmpeq",
+ "cmplt",
+ "cmple",
+ "cmpunord",
+ "cmpneq",
+ "cmpnlt",
+ "cmpnle",
+ "cmpord",
+}
+
+var x86_pclmulqOps = []string{
+ "pclmullqlqdq",
+ "pclmulhqlqdq",
+ "pclmullqhqdq",
+ "pclmulhqhqdq",
+}
+
+func x86_countPrefix(inst *x86_Inst, target x86_Prefix) int {
+ n := 0
+ for _, p := range inst.Prefix {
+ if p&0xFF == target&0xFF {
+ n++
+ }
+ }
+ return n
+}
+
+func x86_markLastImplicit(inst *x86_Inst, prefix x86_Prefix) bool {
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ p := inst.Prefix[i]
+ if p&0xFF == prefix {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ return true
+ }
+ }
+ return false
+}
+
+func x86_unmarkImplicit(inst *x86_Inst, prefix x86_Prefix) {
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ p := inst.Prefix[i]
+ if p&0xFF == prefix {
+ inst.Prefix[i] &^= x86_PrefixImplicit
+ }
+ }
+}
+
+func x86_byteSizeSuffix(b int) string {
+ switch b {
+ case 1:
+ return "b"
+ case 2:
+ return "w"
+ case 4:
+ return "l"
+ case 8:
+ return "q"
+ }
+ return ""
+}
+
+func x86_argBytes(inst *x86_Inst, arg x86_Arg) int {
+ if x86_isMem(arg) {
+ return inst.MemBytes
+ }
+ return x86_regBytes(arg)
+}
+
+func x86_isFloat(op x86_Op) bool {
+ switch op {
+ case x86_FADD, x86_FCOM, x86_FCOMP, x86_FDIV, x86_FDIVR, x86_FIADD, x86_FICOM, x86_FICOMP, x86_FIDIV, x86_FIDIVR, x86_FILD, x86_FIMUL, x86_FIST, x86_FISTP, x86_FISTTP, x86_FISUB, x86_FISUBR, x86_FLD, x86_FMUL, x86_FST, x86_FSTP, x86_FSUB, x86_FSUBR:
+ return true
+ }
+ return false
+}
+
+func x86_isFloatInt(op x86_Op) bool {
+ switch op {
+ case x86_FIADD, x86_FICOM, x86_FICOMP, x86_FIDIV, x86_FIDIVR, x86_FILD, x86_FIMUL, x86_FIST, x86_FISTP, x86_FISTTP, x86_FISUB, x86_FISUBR:
+ return true
+ }
+ return false
+}
+
+/* inst.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package x86asm implements decoding of x86 machine code.
+
+// An Inst is a single instruction.
+type x86_Inst struct {
+ Prefix x86_Prefixes // Prefixes applied to the instruction.
+ Op x86_Op // Opcode mnemonic
+ Opcode uint32 // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
+ Args x86_Args // Instruction arguments, in Intel order
+ Mode int // processor mode in bits: 16, 32, or 64
+ AddrSize int // address size in bits: 16, 32, or 64
+ DataSize int // operand size in bits: 16, 32, or 64
+ MemBytes int // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
+ Len int // length of encoded instruction in bytes
+}
+
+// Prefixes is an array of prefixes associated with a single instruction.
+// The prefixes are listed in the same order as found in the instruction:
+// each prefix byte corresponds to one slot in the array. The first zero
+// in the array marks the end of the prefixes.
+type x86_Prefixes [14]x86_Prefix
+
+// A Prefix represents an Intel instruction prefix.
+// The low 8 bits are the actual prefix byte encoding,
+// and the top 8 bits contain distinguishing bits and metadata.
+type x86_Prefix uint16
+
+const (
+ // Metadata about the role of a prefix in an instruction.
+ x86_PrefixImplicit x86_Prefix = 0x8000 // prefix is implied by instruction text
+ x86_PrefixIgnored x86_Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
+ x86_PrefixInvalid x86_Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
+
+ // Memory segment overrides.
+ x86_PrefixES x86_Prefix = 0x26 // ES segment override
+ x86_PrefixCS x86_Prefix = 0x2E // CS segment override
+ x86_PrefixSS x86_Prefix = 0x36 // SS segment override
+ x86_PrefixDS x86_Prefix = 0x3E // DS segment override
+ x86_PrefixFS x86_Prefix = 0x64 // FS segment override
+ x86_PrefixGS x86_Prefix = 0x65 // GS segment override
+
+ // Branch prediction.
+ x86_PrefixPN x86_Prefix = 0x12E // predict not taken (conditional branch only)
+ x86_PrefixPT x86_Prefix = 0x13E // predict taken (conditional branch only)
+
+ // Size attributes.
+ x86_PrefixDataSize x86_Prefix = 0x66 // operand size override
+ x86_PrefixData16 x86_Prefix = 0x166
+ x86_PrefixData32 x86_Prefix = 0x266
+ x86_PrefixAddrSize x86_Prefix = 0x67 // address size override
+ x86_PrefixAddr16 x86_Prefix = 0x167
+ x86_PrefixAddr32 x86_Prefix = 0x267
+
+ // One of a kind.
+ x86_PrefixLOCK x86_Prefix = 0xF0 // lock
+ x86_PrefixREPN x86_Prefix = 0xF2 // repeat not zero
+ x86_PrefixXACQUIRE x86_Prefix = 0x1F2
+ x86_PrefixBND x86_Prefix = 0x2F2
+ x86_PrefixREP x86_Prefix = 0xF3 // repeat
+ x86_PrefixXRELEASE x86_Prefix = 0x1F3
+
+ // The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
+ // the other bits are set or not according to the intended use.
+ x86_PrefixREX x86_Prefix = 0x40 // REX 64-bit extension prefix
+ x86_PrefixREXW x86_Prefix = 0x08 // extension bit W (64-bit instruction width)
+ x86_PrefixREXR x86_Prefix = 0x04 // extension bit R (r field in modrm)
+ x86_PrefixREXX x86_Prefix = 0x02 // extension bit X (index field in sib)
+ x86_PrefixREXB x86_Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
+)
+
+// IsREX reports whether p is a REX prefix byte.
+func (p x86_Prefix) IsREX() bool {
+ return p&0xF0 == x86_PrefixREX
+}
+
+func (p x86_Prefix) String() string {
+ p &^= x86_PrefixImplicit | x86_PrefixIgnored | x86_PrefixInvalid
+ if s := x86_prefixNames[p]; s != "" {
+ return s
+ }
+
+ if p.IsREX() {
+ s := "REX."
+ if p&x86_PrefixREXW != 0 {
+ s += "W"
+ }
+ if p&x86_PrefixREXR != 0 {
+ s += "R"
+ }
+ if p&x86_PrefixREXX != 0 {
+ s += "X"
+ }
+ if p&x86_PrefixREXB != 0 {
+ s += "B"
+ }
+ return s
+ }
+
+ return fmt.Sprintf("Prefix(%#x)", int(p))
+}
+
+// An Op is an x86 opcode.
+type x86_Op uint32
+
+func (op x86_Op) String() string {
+ i := int(op)
+ if i < 0 || i >= len(x86_opNames) || x86_opNames[i] == "" {
+ return fmt.Sprintf("Op(%d)", i)
+ }
+ return x86_opNames[i]
+}
+
+// An Args holds the instruction arguments.
+// If an instruction has fewer than 4 arguments,
+// the final elements in the array are nil.
+type x86_Args [4]x86_Arg
+
+// An Arg is a single instruction argument,
+// one of these types: Reg, Mem, Imm, Rel.
+type x86_Arg interface {
+ String() string
+ isArg()
+}
+
+// Note that the implements of Arg that follow are all sized
+// so that on a 64-bit machine the data can be inlined in
+// the interface value instead of requiring an allocation.
+
+// A Reg is a single register.
+// The zero Reg value has no name but indicates ``no register.''
+type x86_Reg uint8
+
+const (
+ _ x86_Reg = iota
+
+ // 8-bit
+ x86_AL
+ x86_CL
+ x86_DL
+ x86_BL
+ x86_AH
+ x86_CH
+ x86_DH
+ x86_BH
+ x86_SPB
+ x86_BPB
+ x86_SIB
+ x86_DIB
+ x86_R8B
+ x86_R9B
+ x86_R10B
+ x86_R11B
+ x86_R12B
+ x86_R13B
+ x86_R14B
+ x86_R15B
+
+ // 16-bit
+ x86_AX
+ x86_CX
+ x86_DX
+ x86_BX
+ x86_SP
+ x86_BP
+ x86_SI
+ x86_DI
+ x86_R8W
+ x86_R9W
+ x86_R10W
+ x86_R11W
+ x86_R12W
+ x86_R13W
+ x86_R14W
+ x86_R15W
+
+ // 32-bit
+ x86_EAX
+ x86_ECX
+ x86_EDX
+ x86_EBX
+ x86_ESP
+ x86_EBP
+ x86_ESI
+ x86_EDI
+ x86_R8L
+ x86_R9L
+ x86_R10L
+ x86_R11L
+ x86_R12L
+ x86_R13L
+ x86_R14L
+ x86_R15L
+
+ // 64-bit
+ x86_RAX
+ x86_RCX
+ x86_RDX
+ x86_RBX
+ x86_RSP
+ x86_RBP
+ x86_RSI
+ x86_RDI
+ x86_R8
+ x86_R9
+ x86_R10
+ x86_R11
+ x86_R12
+ x86_R13
+ x86_R14
+ x86_R15
+
+ // Instruction pointer.
+ x86_IP // 16-bit
+ x86_EIP // 32-bit
+ x86_RIP // 64-bit
+
+ // 387 floating point registers.
+ x86_F0
+ x86_F1
+ x86_F2
+ x86_F3
+ x86_F4
+ x86_F5
+ x86_F6
+ x86_F7
+
+ // MMX registers.
+ x86_M0
+ x86_M1
+ x86_M2
+ x86_M3
+ x86_M4
+ x86_M5
+ x86_M6
+ x86_M7
+
+ // XMM registers.
+ x86_X0
+ x86_X1
+ x86_X2
+ x86_X3
+ x86_X4
+ x86_X5
+ x86_X6
+ x86_X7
+ x86_X8
+ x86_X9
+ x86_X10
+ x86_X11
+ x86_X12
+ x86_X13
+ x86_X14
+ x86_X15
+
+ // Segment registers.
+ x86_ES
+ x86_CS
+ x86_SS
+ x86_DS
+ x86_FS
+ x86_GS
+
+ // System registers.
+ x86_GDTR
+ x86_IDTR
+ x86_LDTR
+ x86_MSW
+ x86_TASK
+
+ // Control registers.
+ x86_CR0
+ x86_CR1
+ x86_CR2
+ x86_CR3
+ x86_CR4
+ x86_CR5
+ x86_CR6
+ x86_CR7
+ x86_CR8
+ x86_CR9
+ x86_CR10
+ x86_CR11
+ x86_CR12
+ x86_CR13
+ x86_CR14
+ x86_CR15
+
+ // Debug registers.
+ x86_DR0
+ x86_DR1
+ x86_DR2
+ x86_DR3
+ x86_DR4
+ x86_DR5
+ x86_DR6
+ x86_DR7
+ x86_DR8
+ x86_DR9
+ x86_DR10
+ x86_DR11
+ x86_DR12
+ x86_DR13
+ x86_DR14
+ x86_DR15
+
+ // Task registers.
+ x86_TR0
+ x86_TR1
+ x86_TR2
+ x86_TR3
+ x86_TR4
+ x86_TR5
+ x86_TR6
+ x86_TR7
+)
+
+const x86_regMax = x86_TR7
+
+func (x86_Reg) isArg() {}
+
+func (r x86_Reg) String() string {
+ i := int(r)
+ if i < 0 || i >= len(x86_regNames) || x86_regNames[i] == "" {
+ return fmt.Sprintf("Reg(%d)", i)
+ }
+ return x86_regNames[i]
+}
+
+// A Mem is a memory reference.
+// The general form is Segment:[Base+Scale*Index+Disp].
+type x86_Mem struct {
+ Segment x86_Reg
+ Base x86_Reg
+ Scale uint8
+ Index x86_Reg
+ Disp int64
+}
+
+func (x86_Mem) isArg() {}
+
+func (m x86_Mem) String() string {
+ var base, plus, scale, index, disp string
+
+ if m.Base != 0 {
+ base = m.Base.String()
+ }
+ if m.Scale != 0 {
+ if m.Base != 0 {
+ plus = "+"
+ }
+ if m.Scale > 1 {
+ scale = fmt.Sprintf("%d*", m.Scale)
+ }
+ index = m.Index.String()
+ }
+ if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
+ disp = fmt.Sprintf("%+#x", m.Disp)
+ }
+ return "[" + base + plus + scale + index + disp + "]"
+}
+
+// A Rel is an offset relative to the current instruction pointer.
+type x86_Rel int32
+
+func (x86_Rel) isArg() {}
+
+func (r x86_Rel) String() string {
+ return fmt.Sprintf(".%+d", r)
+}
+
+// An Imm is an integer constant.
+type x86_Imm int64
+
+func (x86_Imm) isArg() {}
+
+func (i x86_Imm) String() string {
+ return fmt.Sprintf("%#x", int64(i))
+}
+
+func (i x86_Inst) String() string {
+ var buf bytes.Buffer
+ for _, p := range i.Prefix {
+ if p == 0 {
+ break
+ }
+ if p&x86_PrefixImplicit != 0 {
+ continue
+ }
+ fmt.Fprintf(&buf, "%v ", p)
+ }
+ fmt.Fprintf(&buf, "%v", i.Op)
+ sep := " "
+ for _, v := range i.Args {
+ if v == nil {
+ break
+ }
+ fmt.Fprintf(&buf, "%s%v", sep, v)
+ sep = ", "
+ }
+ return buf.String()
+}
+
+func x86_isReg(a x86_Arg) bool {
+ _, ok := a.(x86_Reg)
+ return ok
+}
+
+func x86_isSegReg(a x86_Arg) bool {
+ r, ok := a.(x86_Reg)
+ return ok && x86_ES <= r && r <= x86_GS
+}
+
+func x86_isMem(a x86_Arg) bool {
+ _, ok := a.(x86_Mem)
+ return ok
+}
+
+func x86_isImm(a x86_Arg) bool {
+ _, ok := a.(x86_Imm)
+ return ok
+}
+
+func x86_regBytes(a x86_Arg) int {
+ r, ok := a.(x86_Reg)
+ if !ok {
+ return 0
+ }
+ if x86_AL <= r && r <= x86_R15B {
+ return 1
+ }
+ if x86_AX <= r && r <= x86_R15W {
+ return 2
+ }
+ if x86_EAX <= r && r <= x86_R15L {
+ return 4
+ }
+ if x86_RAX <= r && r <= x86_R15 {
+ return 8
+ }
+ return 0
+}
+
+func x86_isSegment(p x86_Prefix) bool {
+ switch p {
+ case x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
+ return true
+ }
+ return false
+}
+
+// The Op definitions and string list are in tables.go.
+
+var x86_prefixNames = map[x86_Prefix]string{
+ x86_PrefixCS: "CS",
+ x86_PrefixDS: "DS",
+ x86_PrefixES: "ES",
+ x86_PrefixFS: "FS",
+ x86_PrefixGS: "GS",
+ x86_PrefixSS: "SS",
+ x86_PrefixLOCK: "LOCK",
+ x86_PrefixREP: "REP",
+ x86_PrefixREPN: "REPN",
+ x86_PrefixAddrSize: "ADDRSIZE",
+ x86_PrefixDataSize: "DATASIZE",
+ x86_PrefixAddr16: "ADDR16",
+ x86_PrefixData16: "DATA16",
+ x86_PrefixAddr32: "ADDR32",
+ x86_PrefixData32: "DATA32",
+ x86_PrefixBND: "BND",
+ x86_PrefixXACQUIRE: "XACQUIRE",
+ x86_PrefixXRELEASE: "XRELEASE",
+ x86_PrefixREX: "REX",
+ x86_PrefixPT: "PT",
+ x86_PrefixPN: "PN",
+}
+
+var x86_regNames = [...]string{
+ x86_AL: "AL",
+ x86_CL: "CL",
+ x86_BL: "BL",
+ x86_DL: "DL",
+ x86_AH: "AH",
+ x86_CH: "CH",
+ x86_BH: "BH",
+ x86_DH: "DH",
+ x86_SPB: "SPB",
+ x86_BPB: "BPB",
+ x86_SIB: "SIB",
+ x86_DIB: "DIB",
+ x86_R8B: "R8B",
+ x86_R9B: "R9B",
+ x86_R10B: "R10B",
+ x86_R11B: "R11B",
+ x86_R12B: "R12B",
+ x86_R13B: "R13B",
+ x86_R14B: "R14B",
+ x86_R15B: "R15B",
+ x86_AX: "AX",
+ x86_CX: "CX",
+ x86_BX: "BX",
+ x86_DX: "DX",
+ x86_SP: "SP",
+ x86_BP: "BP",
+ x86_SI: "SI",
+ x86_DI: "DI",
+ x86_R8W: "R8W",
+ x86_R9W: "R9W",
+ x86_R10W: "R10W",
+ x86_R11W: "R11W",
+ x86_R12W: "R12W",
+ x86_R13W: "R13W",
+ x86_R14W: "R14W",
+ x86_R15W: "R15W",
+ x86_EAX: "EAX",
+ x86_ECX: "ECX",
+ x86_EDX: "EDX",
+ x86_EBX: "EBX",
+ x86_ESP: "ESP",
+ x86_EBP: "EBP",
+ x86_ESI: "ESI",
+ x86_EDI: "EDI",
+ x86_R8L: "R8L",
+ x86_R9L: "R9L",
+ x86_R10L: "R10L",
+ x86_R11L: "R11L",
+ x86_R12L: "R12L",
+ x86_R13L: "R13L",
+ x86_R14L: "R14L",
+ x86_R15L: "R15L",
+ x86_RAX: "RAX",
+ x86_RCX: "RCX",
+ x86_RDX: "RDX",
+ x86_RBX: "RBX",
+ x86_RSP: "RSP",
+ x86_RBP: "RBP",
+ x86_RSI: "RSI",
+ x86_RDI: "RDI",
+ x86_R8: "R8",
+ x86_R9: "R9",
+ x86_R10: "R10",
+ x86_R11: "R11",
+ x86_R12: "R12",
+ x86_R13: "R13",
+ x86_R14: "R14",
+ x86_R15: "R15",
+ x86_IP: "IP",
+ x86_EIP: "EIP",
+ x86_RIP: "RIP",
+ x86_F0: "F0",
+ x86_F1: "F1",
+ x86_F2: "F2",
+ x86_F3: "F3",
+ x86_F4: "F4",
+ x86_F5: "F5",
+ x86_F6: "F6",
+ x86_F7: "F7",
+ x86_M0: "M0",
+ x86_M1: "M1",
+ x86_M2: "M2",
+ x86_M3: "M3",
+ x86_M4: "M4",
+ x86_M5: "M5",
+ x86_M6: "M6",
+ x86_M7: "M7",
+ x86_X0: "X0",
+ x86_X1: "X1",
+ x86_X2: "X2",
+ x86_X3: "X3",
+ x86_X4: "X4",
+ x86_X5: "X5",
+ x86_X6: "X6",
+ x86_X7: "X7",
+ x86_X8: "X8",
+ x86_X9: "X9",
+ x86_X10: "X10",
+ x86_X11: "X11",
+ x86_X12: "X12",
+ x86_X13: "X13",
+ x86_X14: "X14",
+ x86_X15: "X15",
+ x86_CS: "CS",
+ x86_SS: "SS",
+ x86_DS: "DS",
+ x86_ES: "ES",
+ x86_FS: "FS",
+ x86_GS: "GS",
+ x86_GDTR: "GDTR",
+ x86_IDTR: "IDTR",
+ x86_LDTR: "LDTR",
+ x86_MSW: "MSW",
+ x86_TASK: "TASK",
+ x86_CR0: "CR0",
+ x86_CR1: "CR1",
+ x86_CR2: "CR2",
+ x86_CR3: "CR3",
+ x86_CR4: "CR4",
+ x86_CR5: "CR5",
+ x86_CR6: "CR6",
+ x86_CR7: "CR7",
+ x86_CR8: "CR8",
+ x86_CR9: "CR9",
+ x86_CR10: "CR10",
+ x86_CR11: "CR11",
+ x86_CR12: "CR12",
+ x86_CR13: "CR13",
+ x86_CR14: "CR14",
+ x86_CR15: "CR15",
+ x86_DR0: "DR0",
+ x86_DR1: "DR1",
+ x86_DR2: "DR2",
+ x86_DR3: "DR3",
+ x86_DR4: "DR4",
+ x86_DR5: "DR5",
+ x86_DR6: "DR6",
+ x86_DR7: "DR7",
+ x86_DR8: "DR8",
+ x86_DR9: "DR9",
+ x86_DR10: "DR10",
+ x86_DR11: "DR11",
+ x86_DR12: "DR12",
+ x86_DR13: "DR13",
+ x86_DR14: "DR14",
+ x86_DR15: "DR15",
+ x86_TR0: "TR0",
+ x86_TR1: "TR1",
+ x86_TR2: "TR2",
+ x86_TR3: "TR3",
+ x86_TR4: "TR4",
+ x86_TR5: "TR5",
+ x86_TR6: "TR6",
+ x86_TR7: "TR7",
+}
+
+/* intel.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// IntelSyntax returns the Intel assembler syntax for the instruction, as defined by Intel's XED tool.
+func x86_IntelSyntax(inst x86_Inst) string {
+ var iargs []x86_Arg
+ for _, a := range inst.Args {
+ if a == nil {
+ break
+ }
+ iargs = append(iargs, a)
+ }
+
+ switch inst.Op {
+ case x86_INSB, x86_INSD, x86_INSW, x86_OUTSB, x86_OUTSD, x86_OUTSW, x86_LOOPNE, x86_JCXZ, x86_JECXZ, x86_JRCXZ, x86_LOOP, x86_LOOPE, x86_MOV, x86_XLATB:
+ if inst.Op == x86_MOV && (inst.Opcode>>16)&0xFFFC != 0x0F20 {
+ break
+ }
+ for i, p := range inst.Prefix {
+ if p&0xFF == x86_PrefixAddrSize {
+ inst.Prefix[i] &^= x86_PrefixImplicit
+ }
+ }
+ }
+
+ switch inst.Op {
+ case x86_MOV:
+ dst, _ := inst.Args[0].(x86_Reg)
+ src, _ := inst.Args[1].(x86_Reg)
+ if x86_ES <= dst && dst <= x86_GS && x86_EAX <= src && src <= x86_R15L {
+ src -= x86_EAX - x86_AX
+ iargs[1] = src
+ }
+ if x86_ES <= dst && dst <= x86_GS && x86_RAX <= src && src <= x86_R15 {
+ src -= x86_RAX - x86_AX
+ iargs[1] = src
+ }
+
+ if inst.Opcode>>24&^3 == 0xA0 {
+ for i, p := range inst.Prefix {
+ if p&0xFF == x86_PrefixAddrSize {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ }
+ }
+ }
+
+ switch inst.Op {
+ case x86_AAM, x86_AAD:
+ if imm, ok := iargs[0].(x86_Imm); ok {
+ if inst.DataSize == 32 {
+ iargs[0] = x86_Imm(uint32(int8(imm)))
+ } else if inst.DataSize == 16 {
+ iargs[0] = x86_Imm(uint16(int8(imm)))
+ }
+ }
+
+ case x86_PUSH:
+ if imm, ok := iargs[0].(x86_Imm); ok {
+ iargs[0] = x86_Imm(uint32(imm))
+ }
+ }
+
+ for _, p := range inst.Prefix {
+ if p&x86_PrefixImplicit != 0 {
+ for j, pj := range inst.Prefix {
+ if pj&0xFF == p&0xFF {
+ inst.Prefix[j] |= x86_PrefixImplicit
+ }
+ }
+ }
+ }
+
+ if inst.Op != 0 {
+ for i, p := range inst.Prefix {
+ switch p &^ x86_PrefixIgnored {
+ case x86_PrefixData16, x86_PrefixData32, x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixSS:
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ if p.IsREX() {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ }
+ }
+
+ if x86_isLoop[inst.Op] || inst.Op == x86_JCXZ || inst.Op == x86_JECXZ || inst.Op == x86_JRCXZ {
+ for i, p := range inst.Prefix {
+ if p == x86_PrefixPT || p == x86_PrefixPN {
+ inst.Prefix[i] |= x86_PrefixImplicit
+ }
+ }
+ }
+
+ switch inst.Op {
+ case x86_AAA, x86_AAS, x86_CBW, x86_CDQE, x86_CLC, x86_CLD, x86_CLI, x86_CLTS, x86_CMC, x86_CPUID, x86_CQO, x86_CWD, x86_DAA, x86_DAS,
+ x86_FDECSTP, x86_FINCSTP, x86_FNCLEX, x86_FNINIT, x86_FNOP, x86_FWAIT, x86_HLT,
+ x86_ICEBP, x86_INSB, x86_INSD, x86_INSW, x86_INT, x86_INTO, x86_INVD, x86_IRET, x86_IRETQ,
+ x86_LAHF, x86_LEAVE, x86_LRET, x86_MONITOR, x86_MWAIT, x86_NOP, x86_OUTSB, x86_OUTSD, x86_OUTSW,
+ x86_PAUSE, x86_POPA, x86_POPF, x86_POPFQ, x86_PUSHA, x86_PUSHF, x86_PUSHFQ,
+ x86_RDMSR, x86_RDPMC, x86_RDTSC, x86_RDTSCP, x86_RET, x86_RSM,
+ x86_SAHF, x86_STC, x86_STD, x86_STI, x86_SYSENTER, x86_SYSEXIT, x86_SYSRET,
+ x86_UD2, x86_WBINVD, x86_WRMSR, x86_XEND, x86_XLATB, x86_XTEST:
+
+ if inst.Op == x86_NOP && inst.Opcode>>24 != 0x90 {
+ break
+ }
+ if inst.Op == x86_RET && inst.Opcode>>24 != 0xC3 {
+ break
+ }
+ if inst.Op == x86_INT && inst.Opcode>>24 != 0xCC {
+ break
+ }
+ if inst.Op == x86_LRET && inst.Opcode>>24 != 0xcb {
+ break
+ }
+ for i, p := range inst.Prefix {
+ if p&0xFF == x86_PrefixDataSize {
+ inst.Prefix[i] &^= x86_PrefixImplicit | x86_PrefixIgnored
+ }
+ }
+
+ case 0:
+ // ok
+ }
+
+ switch inst.Op {
+ case x86_INSB, x86_INSD, x86_INSW, x86_OUTSB, x86_OUTSD, x86_OUTSW, x86_MONITOR, x86_MWAIT, x86_XLATB:
+ iargs = nil
+
+ case x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ:
+ iargs = iargs[:1]
+
+ case x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ, x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ:
+ iargs = iargs[1:]
+ }
+
+ const (
+ haveData16 = 1 << iota
+ haveData32
+ haveAddr16
+ haveAddr32
+ haveXacquire
+ haveXrelease
+ haveLock
+ haveHintTaken
+ haveHintNotTaken
+ haveBnd
+ )
+ var prefixBits uint32
+ prefix := ""
+ for _, p := range inst.Prefix {
+ if p == 0 {
+ break
+ }
+ if p&0xFF == 0xF3 {
+ prefixBits &^= haveBnd
+ }
+ if p&(x86_PrefixImplicit|x86_PrefixIgnored) != 0 {
+ continue
+ }
+ switch p {
+ default:
+ prefix += strings.ToLower(p.String()) + " "
+ case x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
+ if inst.Op == 0 {
+ prefix += strings.ToLower(p.String()) + " "
+ }
+ case x86_PrefixREPN:
+ prefix += "repne "
+ case x86_PrefixLOCK:
+ prefixBits |= haveLock
+ case x86_PrefixData16, x86_PrefixDataSize:
+ prefixBits |= haveData16
+ case x86_PrefixData32:
+ prefixBits |= haveData32
+ case x86_PrefixAddrSize, x86_PrefixAddr16:
+ prefixBits |= haveAddr16
+ case x86_PrefixAddr32:
+ prefixBits |= haveAddr32
+ case x86_PrefixXACQUIRE:
+ prefixBits |= haveXacquire
+ case x86_PrefixXRELEASE:
+ prefixBits |= haveXrelease
+ case x86_PrefixPT:
+ prefixBits |= haveHintTaken
+ case x86_PrefixPN:
+ prefixBits |= haveHintNotTaken
+ case x86_PrefixBND:
+ prefixBits |= haveBnd
+ }
+ }
+ switch inst.Op {
+ case x86_JMP:
+ if inst.Opcode>>24 == 0xEB {
+ prefixBits &^= haveBnd
+ }
+ case x86_RET, x86_LRET:
+ prefixBits &^= haveData16 | haveData32
+ }
+
+ if prefixBits&haveXacquire != 0 {
+ prefix += "xacquire "
+ }
+ if prefixBits&haveXrelease != 0 {
+ prefix += "xrelease "
+ }
+ if prefixBits&haveLock != 0 {
+ prefix += "lock "
+ }
+ if prefixBits&haveBnd != 0 {
+ prefix += "bnd "
+ }
+ if prefixBits&haveHintTaken != 0 {
+ prefix += "hint-taken "
+ }
+ if prefixBits&haveHintNotTaken != 0 {
+ prefix += "hint-not-taken "
+ }
+ if prefixBits&haveAddr16 != 0 {
+ prefix += "addr16 "
+ }
+ if prefixBits&haveAddr32 != 0 {
+ prefix += "addr32 "
+ }
+ if prefixBits&haveData16 != 0 {
+ prefix += "data16 "
+ }
+ if prefixBits&haveData32 != 0 {
+ prefix += "data32 "
+ }
+
+ if inst.Op == 0 {
+ if prefix == "" {
+ return "<no instruction>"
+ }
+ return prefix[:len(prefix)-1]
+ }
+
+ var args []string
+ for _, a := range iargs {
+ if a == nil {
+ break
+ }
+ args = append(args, x86_intelArg(&inst, a))
+ }
+
+ var op string
+ switch inst.Op {
+ case x86_NOP:
+ if inst.Opcode>>24 == 0x0F {
+ if inst.DataSize == 16 {
+ args = append(args, "ax")
+ } else {
+ args = append(args, "eax")
+ }
+ }
+
+ case x86_BLENDVPD, x86_BLENDVPS, x86_PBLENDVB:
+ args = args[:2]
+
+ case x86_INT:
+ if inst.Opcode>>24 == 0xCC {
+ args = nil
+ op = "int3"
+ }
+
+ case x86_LCALL, x86_LJMP:
+ if len(args) == 2 {
+ args[0], args[1] = args[1], args[0]
+ }
+
+ case x86_FCHS, x86_FABS, x86_FTST, x86_FLDPI, x86_FLDL2E, x86_FLDLG2, x86_F2XM1, x86_FXAM, x86_FLD1, x86_FLDL2T, x86_FSQRT, x86_FRNDINT, x86_FCOS, x86_FSIN:
+ if len(args) == 0 {
+ args = append(args, "st0")
+ }
+
+ case x86_FPTAN, x86_FSINCOS, x86_FUCOMPP, x86_FCOMPP, x86_FYL2X, x86_FPATAN, x86_FXTRACT, x86_FPREM1, x86_FPREM, x86_FYL2XP1, x86_FSCALE:
+ if len(args) == 0 {
+ args = []string{"st0", "st1"}
+ }
+
+ case x86_FST, x86_FSTP, x86_FISTTP, x86_FIST, x86_FISTP, x86_FBSTP:
+ if len(args) == 1 {
+ args = append(args, "st0")
+ }
+
+ case x86_FLD, x86_FXCH, x86_FCOM, x86_FCOMP, x86_FIADD, x86_FIMUL, x86_FICOM, x86_FICOMP, x86_FISUBR, x86_FIDIV, x86_FUCOM, x86_FUCOMP, x86_FILD, x86_FBLD, x86_FADD, x86_FMUL, x86_FSUB, x86_FSUBR, x86_FISUB, x86_FDIV, x86_FDIVR, x86_FIDIVR:
+ if len(args) == 1 {
+ args = []string{"st0", args[0]}
+ }
+
+ case x86_MASKMOVDQU, x86_MASKMOVQ, x86_XLATB, x86_OUTSB, x86_OUTSW, x86_OUTSD:
+ FixSegment:
+ for i := len(inst.Prefix) - 1; i >= 0; i-- {
+ p := inst.Prefix[i] & 0xFF
+ switch p {
+ case x86_PrefixCS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
+ if inst.Mode != 64 || p == x86_PrefixFS || p == x86_PrefixGS {
+ args = append(args, strings.ToLower((inst.Prefix[i] & 0xFF).String()))
+ break FixSegment
+ }
+ case x86_PrefixDS:
+ if inst.Mode != 64 {
+ break FixSegment
+ }
+ }
+ }
+ }
+
+ if op == "" {
+ op = x86_intelOp[inst.Op]
+ }
+ if op == "" {
+ op = strings.ToLower(inst.Op.String())
+ }
+ if args != nil {
+ op += " " + strings.Join(args, ", ")
+ }
+ return prefix + op
+}
+
+func x86_intelArg(inst *x86_Inst, arg x86_Arg) string {
+ switch a := arg.(type) {
+ case x86_Imm:
+ if inst.Mode == 32 {
+ return fmt.Sprintf("%#x", uint32(a))
+ }
+ if x86_Imm(int32(a)) == a {
+ return fmt.Sprintf("%#x", int64(a))
+ }
+ return fmt.Sprintf("%#x", uint64(a))
+ case x86_Mem:
+ if a.Base == x86_EIP {
+ a.Base = x86_RIP
+ }
+ prefix := ""
+ switch inst.MemBytes {
+ case 1:
+ prefix = "byte "
+ case 2:
+ prefix = "word "
+ case 4:
+ prefix = "dword "
+ case 8:
+ prefix = "qword "
+ case 16:
+ prefix = "xmmword "
+ }
+ switch inst.Op {
+ case x86_INVLPG:
+ prefix = "byte "
+ case x86_STOSB, x86_MOVSB, x86_CMPSB, x86_LODSB, x86_SCASB:
+ prefix = "byte "
+ case x86_STOSW, x86_MOVSW, x86_CMPSW, x86_LODSW, x86_SCASW:
+ prefix = "word "
+ case x86_STOSD, x86_MOVSD, x86_CMPSD, x86_LODSD, x86_SCASD:
+ prefix = "dword "
+ case x86_STOSQ, x86_MOVSQ, x86_CMPSQ, x86_LODSQ, x86_SCASQ:
+ prefix = "qword "
+ case x86_LAR:
+ prefix = "word "
+ case x86_BOUND:
+ if inst.Mode == 32 {
+ prefix = "qword "
+ } else {
+ prefix = "dword "
+ }
+ case x86_PREFETCHW, x86_PREFETCHNTA, x86_PREFETCHT0, x86_PREFETCHT1, x86_PREFETCHT2, x86_CLFLUSH:
+ prefix = "zmmword "
+ }
+ switch inst.Op {
+ case x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ, x86_CMPSB, x86_CMPSW, x86_CMPSD, x86_CMPSQ, x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ, x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ, x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ:
+ switch a.Base {
+ case x86_DI, x86_EDI, x86_RDI:
+ if a.Segment == x86_ES {
+ a.Segment = 0
+ }
+ case x86_SI, x86_ESI, x86_RSI:
+ if a.Segment == x86_DS {
+ a.Segment = 0
+ }
+ }
+ case x86_LEA:
+ a.Segment = 0
+ default:
+ switch a.Base {
+ case x86_SP, x86_ESP, x86_RSP, x86_BP, x86_EBP, x86_RBP:
+ if a.Segment == x86_SS {
+ a.Segment = 0
+ }
+ default:
+ if a.Segment == x86_DS {
+ a.Segment = 0
+ }
+ }
+ }
+
+ if inst.Mode == 64 && a.Segment != x86_FS && a.Segment != x86_GS {
+ a.Segment = 0
+ }
+
+ prefix += "ptr "
+ if a.Segment != 0 {
+ prefix += strings.ToLower(a.Segment.String()) + ":"
+ }
+ prefix += "["
+ if a.Base != 0 {
+ prefix += x86_intelArg(inst, a.Base)
+ }
+ if a.Scale != 0 && a.Index != 0 {
+ if a.Base != 0 {
+ prefix += "+"
+ }
+ prefix += fmt.Sprintf("%s*%d", x86_intelArg(inst, a.Index), a.Scale)
+ }
+ if a.Disp != 0 {
+ if prefix[len(prefix)-1] == '[' && (a.Disp >= 0 || int64(int32(a.Disp)) != a.Disp) {
+ prefix += fmt.Sprintf("%#x", uint64(a.Disp))
+ } else {
+ prefix += fmt.Sprintf("%+#x", a.Disp)
+ }
+ }
+ prefix += "]"
+ return prefix
+ case x86_Rel:
+ return fmt.Sprintf(".%+#x", int64(a))
+ case x86_Reg:
+ if int(a) < len(x86_intelReg) && x86_intelReg[a] != "" {
+ return x86_intelReg[a]
+ }
+ }
+ return strings.ToLower(arg.String())
+}
+
+var x86_intelOp = map[x86_Op]string{
+ x86_JAE: "jnb",
+ x86_JA: "jnbe",
+ x86_JGE: "jnl",
+ x86_JNE: "jnz",
+ x86_JG: "jnle",
+ x86_JE: "jz",
+ x86_SETAE: "setnb",
+ x86_SETA: "setnbe",
+ x86_SETGE: "setnl",
+ x86_SETNE: "setnz",
+ x86_SETG: "setnle",
+ x86_SETE: "setz",
+ x86_CMOVAE: "cmovnb",
+ x86_CMOVA: "cmovnbe",
+ x86_CMOVGE: "cmovnl",
+ x86_CMOVNE: "cmovnz",
+ x86_CMOVG: "cmovnle",
+ x86_CMOVE: "cmovz",
+ x86_LCALL: "call far",
+ x86_LJMP: "jmp far",
+ x86_LRET: "ret far",
+ x86_ICEBP: "int1",
+ x86_MOVSD_XMM: "movsd",
+ x86_XLATB: "xlat",
+}
+
+var x86_intelReg = [...]string{
+ x86_F0: "st0",
+ x86_F1: "st1",
+ x86_F2: "st2",
+ x86_F3: "st3",
+ x86_F4: "st4",
+ x86_F5: "st5",
+ x86_F6: "st6",
+ x86_F7: "st7",
+ x86_M0: "mmx0",
+ x86_M1: "mmx1",
+ x86_M2: "mmx2",
+ x86_M3: "mmx3",
+ x86_M4: "mmx4",
+ x86_M5: "mmx5",
+ x86_M6: "mmx6",
+ x86_M7: "mmx7",
+ x86_X0: "xmm0",
+ x86_X1: "xmm1",
+ x86_X2: "xmm2",
+ x86_X3: "xmm3",
+ x86_X4: "xmm4",
+ x86_X5: "xmm5",
+ x86_X6: "xmm6",
+ x86_X7: "xmm7",
+ x86_X8: "xmm8",
+ x86_X9: "xmm9",
+ x86_X10: "xmm10",
+ x86_X11: "xmm11",
+ x86_X12: "xmm12",
+ x86_X13: "xmm13",
+ x86_X14: "xmm14",
+ x86_X15: "xmm15",
+
+ // TODO: Maybe the constants are named wrong.
+ x86_SPB: "spl",
+ x86_BPB: "bpl",
+ x86_SIB: "sil",
+ x86_DIB: "dil",
+
+ x86_R8L: "r8d",
+ x86_R9L: "r9d",
+ x86_R10L: "r10d",
+ x86_R11L: "r11d",
+ x86_R12L: "r12d",
+ x86_R13L: "r13d",
+ x86_R14L: "r14d",
+ x86_R15L: "r15d",
+}
+
+/* plan9x.go */
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// plan9Syntax returns the Go assembler syntax for the instruction.
+// The syntax was originally defined by Plan 9.
+// The pc is the program counter of the instruction, used for expanding
+// PC-relative addresses into absolute ones.
+// The symname function queries the symbol table for the program
+// being disassembled. Given a target address it returns the name and base
+// address of the symbol containing the target, if any; otherwise it returns "", 0.
+func x86_plan9Syntax(inst x86_Inst, pc uint64, symname func(uint64) (string, uint64)) string {
+ if symname == nil {
+ symname = func(uint64) (string, uint64) { return "", 0 }
+ }
+ var args []string
+ for i := len(inst.Args) - 1; i >= 0; i-- {
+ a := inst.Args[i]
+ if a == nil {
+ continue
+ }
+ args = append(args, x86_plan9Arg(&inst, pc, symname, a))
+ }
+
+ var last x86_Prefix
+ for _, p := range inst.Prefix {
+ if p == 0 || p.IsREX() {
+ break
+ }
+ last = p
+ }
+
+ prefix := ""
+ switch last & 0xFF {
+ case 0, 0x66, 0x67:
+ // ignore
+ case x86_PrefixREPN:
+ prefix += "REPNE "
+ default:
+ prefix += last.String() + " "
+ }
+
+ op := inst.Op.String()
+ if x86_plan9Suffix[inst.Op] {
+ switch inst.DataSize {
+ case 8:
+ op += "B"
+ case 16:
+ op += "W"
+ case 32:
+ op += "L"
+ case 64:
+ op += "Q"
+ }
+ }
+
+ if args != nil {
+ op += " " + strings.Join(args, ", ")
+ }
+
+ return prefix + op
+}
+
+func x86_plan9Arg(inst *x86_Inst, pc uint64, symname func(uint64) (string, uint64), arg x86_Arg) string {
+ switch a := arg.(type) {
+ case x86_Reg:
+ return x86_plan9Reg[a]
+ case x86_Rel:
+ if pc == 0 {
+ break
+ }
+ // If the absolute address is the start of a symbol, use the name.
+ // Otherwise use the raw address, so that things like relative
+ // jumps show up as JMP 0x123 instead of JMP f+10(SB).
+ // It is usually easier to search for 0x123 than to do the mental
+ // arithmetic to find f+10.
+ addr := pc + uint64(inst.Len) + uint64(a)
+ if s, base := symname(addr); s != "" && addr == base {
+ return fmt.Sprintf("%s(SB)", s)
+ }
+ return fmt.Sprintf("%#x", addr)
+
+ case x86_Imm:
+ if s, base := symname(uint64(a)); s != "" {
+ suffix := ""
+ if uint64(a) != base {
+ suffix = fmt.Sprintf("%+d", uint64(a)-base)
+ }
+ return fmt.Sprintf("$%s%s(SB)", s, suffix)
+ }
+ if inst.Mode == 32 {
+ return fmt.Sprintf("$%#x", uint32(a))
+ }
+ if x86_Imm(int32(a)) == a {
+ return fmt.Sprintf("$%#x", int64(a))
+ }
+ return fmt.Sprintf("$%#x", uint64(a))
+ case x86_Mem:
+ if a.Segment == 0 && a.Disp != 0 && a.Base == 0 && (a.Index == 0 || a.Scale == 0) {
+ if s, base := symname(uint64(a.Disp)); s != "" {
+ suffix := ""
+ if uint64(a.Disp) != base {
+ suffix = fmt.Sprintf("%+d", uint64(a.Disp)-base)
+ }
+ return fmt.Sprintf("%s%s(SB)", s, suffix)
+ }
+ }
+ s := ""
+ if a.Segment != 0 {
+ s += fmt.Sprintf("%s:", x86_plan9Reg[a.Segment])
+ }
+ if a.Disp != 0 {
+ s += fmt.Sprintf("%#x", a.Disp)
+ } else {
+ s += "0"
+ }
+ if a.Base != 0 {
+ s += fmt.Sprintf("(%s)", x86_plan9Reg[a.Base])
+ }
+ if a.Index != 0 && a.Scale != 0 {
+ s += fmt.Sprintf("(%s*%d)", x86_plan9Reg[a.Index], a.Scale)
+ }
+ return s
+ }
+ return arg.String()
+}
+
+var x86_plan9Suffix = [x86_maxOp + 1]bool{
+ x86_ADC: true,
+ x86_ADD: true,
+ x86_AND: true,
+ x86_BSF: true,
+ x86_BSR: true,
+ x86_BT: true,
+ x86_BTC: true,
+ x86_BTR: true,
+ x86_BTS: true,
+ x86_CMP: true,
+ x86_CMPXCHG: true,
+ x86_CVTSI2SD: true,
+ x86_CVTSI2SS: true,
+ x86_CVTSD2SI: true,
+ x86_CVTSS2SI: true,
+ x86_CVTTSD2SI: true,
+ x86_CVTTSS2SI: true,
+ x86_DEC: true,
+ x86_DIV: true,
+ x86_FLDENV: true,
+ x86_FRSTOR: true,
+ x86_IDIV: true,
+ x86_IMUL: true,
+ x86_IN: true,
+ x86_INC: true,
+ x86_LEA: true,
+ x86_MOV: true,
+ x86_MOVNTI: true,
+ x86_MUL: true,
+ x86_NEG: true,
+ x86_NOP: true,
+ x86_NOT: true,
+ x86_OR: true,
+ x86_OUT: true,
+ x86_POP: true,
+ x86_POPA: true,
+ x86_PUSH: true,
+ x86_PUSHA: true,
+ x86_RCL: true,
+ x86_RCR: true,
+ x86_ROL: true,
+ x86_ROR: true,
+ x86_SAR: true,
+ x86_SBB: true,
+ x86_SHL: true,
+ x86_SHLD: true,
+ x86_SHR: true,
+ x86_SHRD: true,
+ x86_SUB: true,
+ x86_TEST: true,
+ x86_XADD: true,
+ x86_XCHG: true,
+ x86_XOR: true,
+}
+
+var x86_plan9Reg = [...]string{
+ x86_AL: "AL",
+ x86_CL: "CL",
+ x86_BL: "BL",
+ x86_DL: "DL",
+ x86_AH: "AH",
+ x86_CH: "CH",
+ x86_BH: "BH",
+ x86_DH: "DH",
+ x86_SPB: "SP",
+ x86_BPB: "BP",
+ x86_SIB: "SI",
+ x86_DIB: "DI",
+ x86_R8B: "R8",
+ x86_R9B: "R9",
+ x86_R10B: "R10",
+ x86_R11B: "R11",
+ x86_R12B: "R12",
+ x86_R13B: "R13",
+ x86_R14B: "R14",
+ x86_R15B: "R15",
+ x86_AX: "AX",
+ x86_CX: "CX",
+ x86_BX: "BX",
+ x86_DX: "DX",
+ x86_SP: "SP",
+ x86_BP: "BP",
+ x86_SI: "SI",
+ x86_DI: "DI",
+ x86_R8W: "R8",
+ x86_R9W: "R9",
+ x86_R10W: "R10",
+ x86_R11W: "R11",
+ x86_R12W: "R12",
+ x86_R13W: "R13",
+ x86_R14W: "R14",
+ x86_R15W: "R15",
+ x86_EAX: "AX",
+ x86_ECX: "CX",
+ x86_EDX: "DX",
+ x86_EBX: "BX",
+ x86_ESP: "SP",
+ x86_EBP: "BP",
+ x86_ESI: "SI",
+ x86_EDI: "DI",
+ x86_R8L: "R8",
+ x86_R9L: "R9",
+ x86_R10L: "R10",
+ x86_R11L: "R11",
+ x86_R12L: "R12",
+ x86_R13L: "R13",
+ x86_R14L: "R14",
+ x86_R15L: "R15",
+ x86_RAX: "AX",
+ x86_RCX: "CX",
+ x86_RDX: "DX",
+ x86_RBX: "BX",
+ x86_RSP: "SP",
+ x86_RBP: "BP",
+ x86_RSI: "SI",
+ x86_RDI: "DI",
+ x86_R8: "R8",
+ x86_R9: "R9",
+ x86_R10: "R10",
+ x86_R11: "R11",
+ x86_R12: "R12",
+ x86_R13: "R13",
+ x86_R14: "R14",
+ x86_R15: "R15",
+ x86_IP: "IP",
+ x86_EIP: "IP",
+ x86_RIP: "IP",
+ x86_F0: "F0",
+ x86_F1: "F1",
+ x86_F2: "F2",
+ x86_F3: "F3",
+ x86_F4: "F4",
+ x86_F5: "F5",
+ x86_F6: "F6",
+ x86_F7: "F7",
+ x86_M0: "M0",
+ x86_M1: "M1",
+ x86_M2: "M2",
+ x86_M3: "M3",
+ x86_M4: "M4",
+ x86_M5: "M5",
+ x86_M6: "M6",
+ x86_M7: "M7",
+ x86_X0: "X0",
+ x86_X1: "X1",
+ x86_X2: "X2",
+ x86_X3: "X3",
+ x86_X4: "X4",
+ x86_X5: "X5",
+ x86_X6: "X6",
+ x86_X7: "X7",
+ x86_X8: "X8",
+ x86_X9: "X9",
+ x86_X10: "X10",
+ x86_X11: "X11",
+ x86_X12: "X12",
+ x86_X13: "X13",
+ x86_X14: "X14",
+ x86_X15: "X15",
+ x86_CS: "CS",
+ x86_SS: "SS",
+ x86_DS: "DS",
+ x86_ES: "ES",
+ x86_FS: "FS",
+ x86_GS: "GS",
+ x86_GDTR: "GDTR",
+ x86_IDTR: "IDTR",
+ x86_LDTR: "LDTR",
+ x86_MSW: "MSW",
+ x86_TASK: "TASK",
+ x86_CR0: "CR0",
+ x86_CR1: "CR1",
+ x86_CR2: "CR2",
+ x86_CR3: "CR3",
+ x86_CR4: "CR4",
+ x86_CR5: "CR5",
+ x86_CR6: "CR6",
+ x86_CR7: "CR7",
+ x86_CR8: "CR8",
+ x86_CR9: "CR9",
+ x86_CR10: "CR10",
+ x86_CR11: "CR11",
+ x86_CR12: "CR12",
+ x86_CR13: "CR13",
+ x86_CR14: "CR14",
+ x86_CR15: "CR15",
+ x86_DR0: "DR0",
+ x86_DR1: "DR1",
+ x86_DR2: "DR2",
+ x86_DR3: "DR3",
+ x86_DR4: "DR4",
+ x86_DR5: "DR5",
+ x86_DR6: "DR6",
+ x86_DR7: "DR7",
+ x86_DR8: "DR8",
+ x86_DR9: "DR9",
+ x86_DR10: "DR10",
+ x86_DR11: "DR11",
+ x86_DR12: "DR12",
+ x86_DR13: "DR13",
+ x86_DR14: "DR14",
+ x86_DR15: "DR15",
+ x86_TR0: "TR0",
+ x86_TR1: "TR1",
+ x86_TR2: "TR2",
+ x86_TR3: "TR3",
+ x86_TR4: "TR4",
+ x86_TR5: "TR5",
+ x86_TR6: "TR6",
+ x86_TR7: "TR7",
+}
+
+/* tables.go */
+
+// DO NOT EDIT
+// generated by: x86map -fmt=decoder ../x86.csv
+
+var x86_decoder = [...]uint16{
+ uint16(x86_xFail),
+ /*1*/ uint16(x86_xCondByte), 243,
+ 0x00, 490,
+ 0x01, 496,
+ 0x02, 525,
+ 0x03, 531,
+ 0x04, 560,
+ 0x05, 566,
+ 0x06, 595,
+ 0x07, 602,
+ 0x08, 609,
+ 0x09, 615,
+ 0x0A, 644,
+ 0x0B, 650,
+ 0x0C, 679,
+ 0x0D, 685,
+ 0x0E, 714,
+ 0x0F, 721,
+ 0x10, 8026,
+ 0x11, 8032,
+ 0x12, 8061,
+ 0x13, 8067,
+ 0x14, 8096,
+ 0x15, 8102,
+ 0x16, 8131,
+ 0x17, 8138,
+ 0x18, 8145,
+ 0x19, 8151,
+ 0x1A, 8180,
+ 0x1B, 8186,
+ 0x1C, 8215,
+ 0x1D, 8221,
+ 0x1E, 8250,
+ 0x1F, 8257,
+ 0x20, 8264,
+ 0x21, 8270,
+ 0x22, 8299,
+ 0x23, 8305,
+ 0x24, 8334,
+ 0x25, 8340,
+ 0x27, 8369,
+ 0x28, 8375,
+ 0x29, 8381,
+ 0x2A, 8410,
+ 0x2B, 8416,
+ 0x2C, 8445,
+ 0x2D, 8451,
+ 0x2F, 8480,
+ 0x30, 8486,
+ 0x31, 8492,
+ 0x32, 8521,
+ 0x33, 8527,
+ 0x34, 8556,
+ 0x35, 8562,
+ 0x37, 8591,
+ 0x38, 8597,
+ 0x39, 8603,
+ 0x3A, 8632,
+ 0x3B, 8638,
+ 0x3C, 8667,
+ 0x3D, 8673,
+ 0x3F, 8702,
+ 0x40, 8708,
+ 0x41, 8708,
+ 0x42, 8708,
+ 0x43, 8708,
+ 0x44, 8708,
+ 0x45, 8708,
+ 0x46, 8708,
+ 0x47, 8708,
+ 0x48, 8723,
+ 0x49, 8723,
+ 0x4a, 8723,
+ 0x4b, 8723,
+ 0x4c, 8723,
+ 0x4d, 8723,
+ 0x4e, 8723,
+ 0x4f, 8723,
+ 0x50, 8738,
+ 0x51, 8738,
+ 0x52, 8738,
+ 0x53, 8738,
+ 0x54, 8738,
+ 0x55, 8738,
+ 0x56, 8738,
+ 0x57, 8738,
+ 0x58, 8765,
+ 0x59, 8765,
+ 0x5a, 8765,
+ 0x5b, 8765,
+ 0x5c, 8765,
+ 0x5d, 8765,
+ 0x5e, 8765,
+ 0x5f, 8765,
+ 0x60, 8792,
+ 0x61, 8805,
+ 0x62, 8818,
+ 0x63, 8837,
+ 0x68, 8868,
+ 0x69, 8887,
+ 0x6A, 8922,
+ 0x6B, 8927,
+ 0x6C, 8962,
+ 0x6D, 8965,
+ 0x6E, 8978,
+ 0x6F, 8981,
+ 0x70, 8994,
+ 0x71, 8999,
+ 0x72, 9004,
+ 0x73, 9009,
+ 0x74, 9014,
+ 0x75, 9019,
+ 0x76, 9024,
+ 0x77, 9029,
+ 0x78, 9034,
+ 0x79, 9039,
+ 0x7A, 9044,
+ 0x7B, 9049,
+ 0x7C, 9054,
+ 0x7D, 9059,
+ 0x7E, 9064,
+ 0x7F, 9069,
+ 0x80, 9074,
+ 0x81, 9131,
+ 0x83, 9372,
+ 0x84, 9613,
+ 0x85, 9619,
+ 0x86, 9648,
+ 0x87, 9654,
+ 0x88, 9683,
+ 0x89, 9689,
+ 0x8A, 9711,
+ 0x8B, 9717,
+ 0x8C, 9739,
+ 0x8D, 9768,
+ 0x8E, 9797,
+ 0x8F, 9826,
+ 0x90, 9862,
+ 0x91, 9862,
+ 0x92, 9862,
+ 0x93, 9862,
+ 0x94, 9862,
+ 0x95, 9862,
+ 0x96, 9862,
+ 0x97, 9862,
+ 0x98, 9888,
+ 0x99, 9908,
+ 0x9A, 9928,
+ 0x9B, 9945,
+ 0x9C, 9948,
+ 0x9D, 9971,
+ 0x9E, 9994,
+ 0x9F, 9997,
+ 0xA0, 10000,
+ 0xA1, 10019,
+ 0xA2, 10041,
+ 0xA3, 10060,
+ 0xA4, 10082,
+ 0xA5, 10085,
+ 0xA6, 10105,
+ 0xA7, 10108,
+ 0xA8, 10128,
+ 0xA9, 10134,
+ 0xAA, 10163,
+ 0xAB, 10166,
+ 0xAC, 10186,
+ 0xAD, 10189,
+ 0xAE, 10209,
+ 0xAF, 10212,
+ 0xb0, 10232,
+ 0xb1, 10232,
+ 0xb2, 10232,
+ 0xb3, 10232,
+ 0xb4, 10232,
+ 0xb5, 10232,
+ 0xb6, 10232,
+ 0xb7, 10232,
+ 0xb8, 10238,
+ 0xb9, 10238,
+ 0xba, 10238,
+ 0xbb, 10238,
+ 0xbc, 10238,
+ 0xbd, 10238,
+ 0xbe, 10238,
+ 0xbf, 10238,
+ 0xC0, 10267,
+ 0xC1, 10318,
+ 0xC2, 10516,
+ 0xC3, 10521,
+ 0xC4, 10524,
+ 0xC5, 10543,
+ 0xC6, 10562,
+ 0xC7, 10586,
+ 0xC8, 10647,
+ 0xC9, 10654,
+ 0xCA, 10677,
+ 0xCB, 10682,
+ 0xCC, 10685,
+ 0xCD, 10689,
+ 0xCE, 10694,
+ 0xCF, 10700,
+ 0xD0, 10720,
+ 0xD1, 10764,
+ 0xD2, 10955,
+ 0xD3, 10999,
+ 0xD4, 11190,
+ 0xD5, 11198,
+ 0xD7, 11206,
+ 0xD8, 11219,
+ 0xD9, 11428,
+ 0xDA, 11637,
+ 0xDB, 11769,
+ 0xDC, 11940,
+ 0xDD, 12109,
+ 0xDE, 12248,
+ 0xDF, 12422,
+ 0xE0, 12533,
+ 0xE1, 12538,
+ 0xE2, 12543,
+ 0xE3, 12548,
+ 0xE4, 12574,
+ 0xE5, 12580,
+ 0xE6, 12602,
+ 0xE7, 12608,
+ 0xE8, 12630,
+ 0xE9, 12661,
+ 0xEA, 12692,
+ 0xEB, 12709,
+ 0xEC, 12714,
+ 0xED, 12719,
+ 0xEE, 12738,
+ 0xEF, 12743,
+ 0xF1, 12762,
+ 0xF4, 12765,
+ 0xF5, 12768,
+ 0xF6, 12771,
+ 0xF7, 12810,
+ 0xF8, 12986,
+ 0xF9, 12989,
+ 0xFA, 12992,
+ 0xFB, 12995,
+ 0xFC, 12998,
+ 0xFD, 13001,
+ 0xFE, 13004,
+ 0xFF, 13021,
+ uint16(x86_xFail),
+ /*490*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*492*/ uint16(x86_xReadSlashR),
+ /*493*/ uint16(x86_xArgRM8),
+ /*494*/ uint16(x86_xArgR8),
+ /*495*/ uint16(x86_xMatch),
+ /*496*/ uint16(x86_xCondIs64), 499, 515,
+ /*499*/ uint16(x86_xCondDataSize), 503, 509, 0,
+ /*503*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*505*/ uint16(x86_xReadSlashR),
+ /*506*/ uint16(x86_xArgRM16),
+ /*507*/ uint16(x86_xArgR16),
+ /*508*/ uint16(x86_xMatch),
+ /*509*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*511*/ uint16(x86_xReadSlashR),
+ /*512*/ uint16(x86_xArgRM32),
+ /*513*/ uint16(x86_xArgR32),
+ /*514*/ uint16(x86_xMatch),
+ /*515*/ uint16(x86_xCondDataSize), 503, 509, 519,
+ /*519*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*521*/ uint16(x86_xReadSlashR),
+ /*522*/ uint16(x86_xArgRM64),
+ /*523*/ uint16(x86_xArgR64),
+ /*524*/ uint16(x86_xMatch),
+ /*525*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*527*/ uint16(x86_xReadSlashR),
+ /*528*/ uint16(x86_xArgR8),
+ /*529*/ uint16(x86_xArgRM8),
+ /*530*/ uint16(x86_xMatch),
+ /*531*/ uint16(x86_xCondIs64), 534, 550,
+ /*534*/ uint16(x86_xCondDataSize), 538, 544, 0,
+ /*538*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*540*/ uint16(x86_xReadSlashR),
+ /*541*/ uint16(x86_xArgR16),
+ /*542*/ uint16(x86_xArgRM16),
+ /*543*/ uint16(x86_xMatch),
+ /*544*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*546*/ uint16(x86_xReadSlashR),
+ /*547*/ uint16(x86_xArgR32),
+ /*548*/ uint16(x86_xArgRM32),
+ /*549*/ uint16(x86_xMatch),
+ /*550*/ uint16(x86_xCondDataSize), 538, 544, 554,
+ /*554*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*556*/ uint16(x86_xReadSlashR),
+ /*557*/ uint16(x86_xArgR64),
+ /*558*/ uint16(x86_xArgRM64),
+ /*559*/ uint16(x86_xMatch),
+ /*560*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*562*/ uint16(x86_xReadIb),
+ /*563*/ uint16(x86_xArgAL),
+ /*564*/ uint16(x86_xArgImm8u),
+ /*565*/ uint16(x86_xMatch),
+ /*566*/ uint16(x86_xCondIs64), 569, 585,
+ /*569*/ uint16(x86_xCondDataSize), 573, 579, 0,
+ /*573*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*575*/ uint16(x86_xReadIw),
+ /*576*/ uint16(x86_xArgAX),
+ /*577*/ uint16(x86_xArgImm16),
+ /*578*/ uint16(x86_xMatch),
+ /*579*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*581*/ uint16(x86_xReadId),
+ /*582*/ uint16(x86_xArgEAX),
+ /*583*/ uint16(x86_xArgImm32),
+ /*584*/ uint16(x86_xMatch),
+ /*585*/ uint16(x86_xCondDataSize), 573, 579, 589,
+ /*589*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*591*/ uint16(x86_xReadId),
+ /*592*/ uint16(x86_xArgRAX),
+ /*593*/ uint16(x86_xArgImm32),
+ /*594*/ uint16(x86_xMatch),
+ /*595*/ uint16(x86_xCondIs64), 598, 0,
+ /*598*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*600*/ uint16(x86_xArgES),
+ /*601*/ uint16(x86_xMatch),
+ /*602*/ uint16(x86_xCondIs64), 605, 0,
+ /*605*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*607*/ uint16(x86_xArgES),
+ /*608*/ uint16(x86_xMatch),
+ /*609*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*611*/ uint16(x86_xReadSlashR),
+ /*612*/ uint16(x86_xArgRM8),
+ /*613*/ uint16(x86_xArgR8),
+ /*614*/ uint16(x86_xMatch),
+ /*615*/ uint16(x86_xCondIs64), 618, 634,
+ /*618*/ uint16(x86_xCondDataSize), 622, 628, 0,
+ /*622*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*624*/ uint16(x86_xReadSlashR),
+ /*625*/ uint16(x86_xArgRM16),
+ /*626*/ uint16(x86_xArgR16),
+ /*627*/ uint16(x86_xMatch),
+ /*628*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*630*/ uint16(x86_xReadSlashR),
+ /*631*/ uint16(x86_xArgRM32),
+ /*632*/ uint16(x86_xArgR32),
+ /*633*/ uint16(x86_xMatch),
+ /*634*/ uint16(x86_xCondDataSize), 622, 628, 638,
+ /*638*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*640*/ uint16(x86_xReadSlashR),
+ /*641*/ uint16(x86_xArgRM64),
+ /*642*/ uint16(x86_xArgR64),
+ /*643*/ uint16(x86_xMatch),
+ /*644*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*646*/ uint16(x86_xReadSlashR),
+ /*647*/ uint16(x86_xArgR8),
+ /*648*/ uint16(x86_xArgRM8),
+ /*649*/ uint16(x86_xMatch),
+ /*650*/ uint16(x86_xCondIs64), 653, 669,
+ /*653*/ uint16(x86_xCondDataSize), 657, 663, 0,
+ /*657*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*659*/ uint16(x86_xReadSlashR),
+ /*660*/ uint16(x86_xArgR16),
+ /*661*/ uint16(x86_xArgRM16),
+ /*662*/ uint16(x86_xMatch),
+ /*663*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*665*/ uint16(x86_xReadSlashR),
+ /*666*/ uint16(x86_xArgR32),
+ /*667*/ uint16(x86_xArgRM32),
+ /*668*/ uint16(x86_xMatch),
+ /*669*/ uint16(x86_xCondDataSize), 657, 663, 673,
+ /*673*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*675*/ uint16(x86_xReadSlashR),
+ /*676*/ uint16(x86_xArgR64),
+ /*677*/ uint16(x86_xArgRM64),
+ /*678*/ uint16(x86_xMatch),
+ /*679*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*681*/ uint16(x86_xReadIb),
+ /*682*/ uint16(x86_xArgAL),
+ /*683*/ uint16(x86_xArgImm8u),
+ /*684*/ uint16(x86_xMatch),
+ /*685*/ uint16(x86_xCondIs64), 688, 704,
+ /*688*/ uint16(x86_xCondDataSize), 692, 698, 0,
+ /*692*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*694*/ uint16(x86_xReadIw),
+ /*695*/ uint16(x86_xArgAX),
+ /*696*/ uint16(x86_xArgImm16),
+ /*697*/ uint16(x86_xMatch),
+ /*698*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*700*/ uint16(x86_xReadId),
+ /*701*/ uint16(x86_xArgEAX),
+ /*702*/ uint16(x86_xArgImm32),
+ /*703*/ uint16(x86_xMatch),
+ /*704*/ uint16(x86_xCondDataSize), 692, 698, 708,
+ /*708*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*710*/ uint16(x86_xReadId),
+ /*711*/ uint16(x86_xArgRAX),
+ /*712*/ uint16(x86_xArgImm32),
+ /*713*/ uint16(x86_xMatch),
+ /*714*/ uint16(x86_xCondIs64), 717, 0,
+ /*717*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*719*/ uint16(x86_xArgCS),
+ /*720*/ uint16(x86_xMatch),
+ /*721*/ uint16(x86_xCondByte), 228,
+ 0x00, 1180,
+ 0x01, 1237,
+ 0x02, 1345,
+ 0x03, 1367,
+ 0x05, 1389,
+ 0x06, 1395,
+ 0x07, 1398,
+ 0x08, 1404,
+ 0x09, 1407,
+ 0x0B, 1410,
+ 0x0D, 1413,
+ 0x10, 1426,
+ 0x11, 1460,
+ 0x12, 1494,
+ 0x13, 1537,
+ 0x14, 1555,
+ 0x15, 1573,
+ 0x16, 1591,
+ 0x17, 1626,
+ 0x18, 1644,
+ 0x1F, 1669,
+ 0x20, 1690,
+ 0x21, 1705,
+ 0x22, 1720,
+ 0x23, 1735,
+ 0x24, 1750,
+ 0x26, 1765,
+ 0x28, 1780,
+ 0x29, 1798,
+ 0x2A, 1816,
+ 0x2B, 1903,
+ 0x2C, 1937,
+ 0x2D, 2024,
+ 0x2E, 2111,
+ 0x2F, 2129,
+ 0x30, 2147,
+ 0x31, 2150,
+ 0x32, 2153,
+ 0x33, 2156,
+ 0x34, 2159,
+ 0x35, 2162,
+ 0x38, 2172,
+ 0x3A, 3073,
+ 0x40, 3484,
+ 0x41, 3513,
+ 0x42, 3542,
+ 0x43, 3571,
+ 0x44, 3600,
+ 0x45, 3629,
+ 0x46, 3658,
+ 0x47, 3687,
+ 0x48, 3716,
+ 0x49, 3745,
+ 0x4A, 3774,
+ 0x4B, 3803,
+ 0x4C, 3832,
+ 0x4D, 3861,
+ 0x4E, 3890,
+ 0x4F, 3919,
+ 0x50, 3948,
+ 0x51, 3966,
+ 0x52, 4000,
+ 0x53, 4018,
+ 0x54, 4036,
+ 0x55, 4054,
+ 0x56, 4072,
+ 0x57, 4090,
+ 0x58, 4108,
+ 0x59, 4142,
+ 0x5A, 4176,
+ 0x5B, 4210,
+ 0x5C, 4236,
+ 0x5D, 4270,
+ 0x5E, 4304,
+ 0x5F, 4338,
+ 0x60, 4372,
+ 0x61, 4390,
+ 0x62, 4408,
+ 0x63, 4426,
+ 0x64, 4444,
+ 0x65, 4462,
+ 0x66, 4480,
+ 0x67, 4498,
+ 0x68, 4516,
+ 0x69, 4534,
+ 0x6A, 4552,
+ 0x6B, 4570,
+ 0x6C, 4588,
+ 0x6D, 4598,
+ 0x6E, 4608,
+ 0x6F, 4675,
+ 0x70, 4701,
+ 0x71, 4743,
+ 0x72, 4806,
+ 0x73, 4869,
+ 0x74, 4934,
+ 0x75, 4952,
+ 0x76, 4970,
+ 0x77, 4988,
+ 0x7C, 4991,
+ 0x7D, 5009,
+ 0x7E, 5027,
+ 0x7F, 5104,
+ 0x80, 5130,
+ 0x81, 5161,
+ 0x82, 5192,
+ 0x83, 5223,
+ 0x84, 5254,
+ 0x85, 5285,
+ 0x86, 5316,
+ 0x87, 5347,
+ 0x88, 5378,
+ 0x89, 5409,
+ 0x8A, 5440,
+ 0x8B, 5471,
+ 0x8C, 5502,
+ 0x8D, 5533,
+ 0x8E, 5564,
+ 0x8F, 5595,
+ 0x90, 5626,
+ 0x91, 5631,
+ 0x92, 5636,
+ 0x93, 5641,
+ 0x94, 5646,
+ 0x95, 5651,
+ 0x96, 5656,
+ 0x97, 5661,
+ 0x98, 5666,
+ 0x99, 5671,
+ 0x9A, 5676,
+ 0x9B, 5681,
+ 0x9C, 5686,
+ 0x9D, 5691,
+ 0x9E, 5696,
+ 0x9F, 5701,
+ 0xA0, 5706,
+ 0xA1, 5710,
+ 0xA2, 5737,
+ 0xA3, 5740,
+ 0xA4, 5769,
+ 0xA5, 5804,
+ 0xA8, 5836,
+ 0xA9, 5840,
+ 0xAA, 5867,
+ 0xAB, 5870,
+ 0xAC, 5899,
+ 0xAD, 5934,
+ 0xAE, 5966,
+ 0xAF, 6224,
+ 0xB0, 6253,
+ 0xB1, 6259,
+ 0xB2, 6288,
+ 0xB3, 6317,
+ 0xB4, 6346,
+ 0xB5, 6375,
+ 0xB6, 6404,
+ 0xB7, 6433,
+ 0xB8, 6462,
+ 0xB9, 6499,
+ 0xBA, 6502,
+ 0xBB, 6627,
+ 0xBC, 6656,
+ 0xBD, 6723,
+ 0xBE, 6790,
+ 0xBF, 6819,
+ 0xC0, 6848,
+ 0xC1, 6854,
+ 0xC2, 6883,
+ 0xC3, 6925,
+ 0xC4, 6954,
+ 0xC5, 6976,
+ 0xC6, 6998,
+ 0xC7, 7020,
+ 0xc8, 7149,
+ 0xc9, 7149,
+ 0xca, 7149,
+ 0xcb, 7149,
+ 0xcc, 7149,
+ 0xcd, 7149,
+ 0xce, 7149,
+ 0xcf, 7149,
+ 0xD0, 7172,
+ 0xD1, 7190,
+ 0xD2, 7208,
+ 0xD3, 7226,
+ 0xD4, 7244,
+ 0xD5, 7262,
+ 0xD6, 7280,
+ 0xD7, 7306,
+ 0xD8, 7324,
+ 0xD9, 7342,
+ 0xDA, 7360,
+ 0xDB, 7378,
+ 0xDC, 7396,
+ 0xDD, 7414,
+ 0xDE, 7432,
+ 0xDF, 7450,
+ 0xE0, 7468,
+ 0xE1, 7486,
+ 0xE2, 7504,
+ 0xE3, 7522,
+ 0xE4, 7540,
+ 0xE5, 7558,
+ 0xE6, 7576,
+ 0xE7, 7602,
+ 0xE8, 7620,
+ 0xE9, 7638,
+ 0xEA, 7656,
+ 0xEB, 7674,
+ 0xEC, 7692,
+ 0xED, 7710,
+ 0xEE, 7728,
+ 0xEF, 7746,
+ 0xF0, 7764,
+ 0xF1, 7774,
+ 0xF2, 7792,
+ 0xF3, 7810,
+ 0xF4, 7828,
+ 0xF5, 7846,
+ 0xF6, 7864,
+ 0xF7, 7882,
+ 0xF8, 7900,
+ 0xF9, 7918,
+ 0xFA, 7936,
+ 0xFB, 7954,
+ 0xFC, 7972,
+ 0xFD, 7990,
+ 0xFE, 8008,
+ uint16(x86_xFail),
+ /*1180*/ uint16(x86_xCondSlashR),
+ 1189, // 0
+ 1205, // 1
+ 1221, // 2
+ 1225, // 3
+ 1229, // 4
+ 1233, // 5
+ 0, // 6
+ 0, // 7
+ /*1189*/ uint16(x86_xCondDataSize), 1193, 1197, 1201,
+ /*1193*/ uint16(x86_xSetOp), uint16(x86_SLDT),
+ /*1195*/ uint16(x86_xArgRM16),
+ /*1196*/ uint16(x86_xMatch),
+ /*1197*/ uint16(x86_xSetOp), uint16(x86_SLDT),
+ /*1199*/ uint16(x86_xArgR32M16),
+ /*1200*/ uint16(x86_xMatch),
+ /*1201*/ uint16(x86_xSetOp), uint16(x86_SLDT),
+ /*1203*/ uint16(x86_xArgR64M16),
+ /*1204*/ uint16(x86_xMatch),
+ /*1205*/ uint16(x86_xCondDataSize), 1209, 1213, 1217,
+ /*1209*/ uint16(x86_xSetOp), uint16(x86_STR),
+ /*1211*/ uint16(x86_xArgRM16),
+ /*1212*/ uint16(x86_xMatch),
+ /*1213*/ uint16(x86_xSetOp), uint16(x86_STR),
+ /*1215*/ uint16(x86_xArgR32M16),
+ /*1216*/ uint16(x86_xMatch),
+ /*1217*/ uint16(x86_xSetOp), uint16(x86_STR),
+ /*1219*/ uint16(x86_xArgR64M16),
+ /*1220*/ uint16(x86_xMatch),
+ /*1221*/ uint16(x86_xSetOp), uint16(x86_LLDT),
+ /*1223*/ uint16(x86_xArgRM16),
+ /*1224*/ uint16(x86_xMatch),
+ /*1225*/ uint16(x86_xSetOp), uint16(x86_LTR),
+ /*1227*/ uint16(x86_xArgRM16),
+ /*1228*/ uint16(x86_xMatch),
+ /*1229*/ uint16(x86_xSetOp), uint16(x86_VERR),
+ /*1231*/ uint16(x86_xArgRM16),
+ /*1232*/ uint16(x86_xMatch),
+ /*1233*/ uint16(x86_xSetOp), uint16(x86_VERW),
+ /*1235*/ uint16(x86_xArgRM16),
+ /*1236*/ uint16(x86_xMatch),
+ /*1237*/ uint16(x86_xCondByte), 8,
+ 0xC8, 1318,
+ 0xC9, 1321,
+ 0xD0, 1324,
+ 0xD1, 1327,
+ 0xD5, 1330,
+ 0xD6, 1333,
+ 0xF8, 1336,
+ 0xF9, 1342,
+ /*1255*/ uint16(x86_xCondSlashR),
+ 1264, // 0
+ 1268, // 1
+ 1272, // 2
+ 1283, // 3
+ 1294, // 4
+ 0, // 5
+ 1310, // 6
+ 1314, // 7
+ /*1264*/ uint16(x86_xSetOp), uint16(x86_SGDT),
+ /*1266*/ uint16(x86_xArgM),
+ /*1267*/ uint16(x86_xMatch),
+ /*1268*/ uint16(x86_xSetOp), uint16(x86_SIDT),
+ /*1270*/ uint16(x86_xArgM),
+ /*1271*/ uint16(x86_xMatch),
+ /*1272*/ uint16(x86_xCondIs64), 1275, 1279,
+ /*1275*/ uint16(x86_xSetOp), uint16(x86_LGDT),
+ /*1277*/ uint16(x86_xArgM16and32),
+ /*1278*/ uint16(x86_xMatch),
+ /*1279*/ uint16(x86_xSetOp), uint16(x86_LGDT),
+ /*1281*/ uint16(x86_xArgM16and64),
+ /*1282*/ uint16(x86_xMatch),
+ /*1283*/ uint16(x86_xCondIs64), 1286, 1290,
+ /*1286*/ uint16(x86_xSetOp), uint16(x86_LIDT),
+ /*1288*/ uint16(x86_xArgM16and32),
+ /*1289*/ uint16(x86_xMatch),
+ /*1290*/ uint16(x86_xSetOp), uint16(x86_LIDT),
+ /*1292*/ uint16(x86_xArgM16and64),
+ /*1293*/ uint16(x86_xMatch),
+ /*1294*/ uint16(x86_xCondDataSize), 1298, 1302, 1306,
+ /*1298*/ uint16(x86_xSetOp), uint16(x86_SMSW),
+ /*1300*/ uint16(x86_xArgRM16),
+ /*1301*/ uint16(x86_xMatch),
+ /*1302*/ uint16(x86_xSetOp), uint16(x86_SMSW),
+ /*1304*/ uint16(x86_xArgR32M16),
+ /*1305*/ uint16(x86_xMatch),
+ /*1306*/ uint16(x86_xSetOp), uint16(x86_SMSW),
+ /*1308*/ uint16(x86_xArgR64M16),
+ /*1309*/ uint16(x86_xMatch),
+ /*1310*/ uint16(x86_xSetOp), uint16(x86_LMSW),
+ /*1312*/ uint16(x86_xArgRM16),
+ /*1313*/ uint16(x86_xMatch),
+ /*1314*/ uint16(x86_xSetOp), uint16(x86_INVLPG),
+ /*1316*/ uint16(x86_xArgM),
+ /*1317*/ uint16(x86_xMatch),
+ /*1318*/ uint16(x86_xSetOp), uint16(x86_MONITOR),
+ /*1320*/ uint16(x86_xMatch),
+ /*1321*/ uint16(x86_xSetOp), uint16(x86_MWAIT),
+ /*1323*/ uint16(x86_xMatch),
+ /*1324*/ uint16(x86_xSetOp), uint16(x86_XGETBV),
+ /*1326*/ uint16(x86_xMatch),
+ /*1327*/ uint16(x86_xSetOp), uint16(x86_XSETBV),
+ /*1329*/ uint16(x86_xMatch),
+ /*1330*/ uint16(x86_xSetOp), uint16(x86_XEND),
+ /*1332*/ uint16(x86_xMatch),
+ /*1333*/ uint16(x86_xSetOp), uint16(x86_XTEST),
+ /*1335*/ uint16(x86_xMatch),
+ /*1336*/ uint16(x86_xCondIs64), 0, 1339,
+ /*1339*/ uint16(x86_xSetOp), uint16(x86_SWAPGS),
+ /*1341*/ uint16(x86_xMatch),
+ /*1342*/ uint16(x86_xSetOp), uint16(x86_RDTSCP),
+ /*1344*/ uint16(x86_xMatch),
+ /*1345*/ uint16(x86_xCondDataSize), 1349, 1355, 1361,
+ /*1349*/ uint16(x86_xSetOp), uint16(x86_LAR),
+ /*1351*/ uint16(x86_xReadSlashR),
+ /*1352*/ uint16(x86_xArgR16),
+ /*1353*/ uint16(x86_xArgRM16),
+ /*1354*/ uint16(x86_xMatch),
+ /*1355*/ uint16(x86_xSetOp), uint16(x86_LAR),
+ /*1357*/ uint16(x86_xReadSlashR),
+ /*1358*/ uint16(x86_xArgR32),
+ /*1359*/ uint16(x86_xArgR32M16),
+ /*1360*/ uint16(x86_xMatch),
+ /*1361*/ uint16(x86_xSetOp), uint16(x86_LAR),
+ /*1363*/ uint16(x86_xReadSlashR),
+ /*1364*/ uint16(x86_xArgR64),
+ /*1365*/ uint16(x86_xArgR64M16),
+ /*1366*/ uint16(x86_xMatch),
+ /*1367*/ uint16(x86_xCondDataSize), 1371, 1377, 1383,
+ /*1371*/ uint16(x86_xSetOp), uint16(x86_LSL),
+ /*1373*/ uint16(x86_xReadSlashR),
+ /*1374*/ uint16(x86_xArgR16),
+ /*1375*/ uint16(x86_xArgRM16),
+ /*1376*/ uint16(x86_xMatch),
+ /*1377*/ uint16(x86_xSetOp), uint16(x86_LSL),
+ /*1379*/ uint16(x86_xReadSlashR),
+ /*1380*/ uint16(x86_xArgR32),
+ /*1381*/ uint16(x86_xArgR32M16),
+ /*1382*/ uint16(x86_xMatch),
+ /*1383*/ uint16(x86_xSetOp), uint16(x86_LSL),
+ /*1385*/ uint16(x86_xReadSlashR),
+ /*1386*/ uint16(x86_xArgR64),
+ /*1387*/ uint16(x86_xArgR32M16),
+ /*1388*/ uint16(x86_xMatch),
+ /*1389*/ uint16(x86_xCondIs64), 0, 1392,
+ /*1392*/ uint16(x86_xSetOp), uint16(x86_SYSCALL),
+ /*1394*/ uint16(x86_xMatch),
+ /*1395*/ uint16(x86_xSetOp), uint16(x86_CLTS),
+ /*1397*/ uint16(x86_xMatch),
+ /*1398*/ uint16(x86_xCondIs64), 0, 1401,
+ /*1401*/ uint16(x86_xSetOp), uint16(x86_SYSRET),
+ /*1403*/ uint16(x86_xMatch),
+ /*1404*/ uint16(x86_xSetOp), uint16(x86_INVD),
+ /*1406*/ uint16(x86_xMatch),
+ /*1407*/ uint16(x86_xSetOp), uint16(x86_WBINVD),
+ /*1409*/ uint16(x86_xMatch),
+ /*1410*/ uint16(x86_xSetOp), uint16(x86_UD2),
+ /*1412*/ uint16(x86_xMatch),
+ /*1413*/ uint16(x86_xCondSlashR),
+ 0, // 0
+ 1422, // 1
+ 0, // 2
+ 0, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*1422*/ uint16(x86_xSetOp), uint16(x86_PREFETCHW),
+ /*1424*/ uint16(x86_xArgM8),
+ /*1425*/ uint16(x86_xMatch),
+ /*1426*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1454,
+ 0xF2, 1448,
+ 0x66, 1442,
+ 0x0, 1436,
+ /*1436*/ uint16(x86_xSetOp), uint16(x86_MOVUPS),
+ /*1438*/ uint16(x86_xReadSlashR),
+ /*1439*/ uint16(x86_xArgXmm1),
+ /*1440*/ uint16(x86_xArgXmm2M128),
+ /*1441*/ uint16(x86_xMatch),
+ /*1442*/ uint16(x86_xSetOp), uint16(x86_MOVUPD),
+ /*1444*/ uint16(x86_xReadSlashR),
+ /*1445*/ uint16(x86_xArgXmm1),
+ /*1446*/ uint16(x86_xArgXmm2M128),
+ /*1447*/ uint16(x86_xMatch),
+ /*1448*/ uint16(x86_xSetOp), uint16(x86_MOVSD_XMM),
+ /*1450*/ uint16(x86_xReadSlashR),
+ /*1451*/ uint16(x86_xArgXmm1),
+ /*1452*/ uint16(x86_xArgXmm2M64),
+ /*1453*/ uint16(x86_xMatch),
+ /*1454*/ uint16(x86_xSetOp), uint16(x86_MOVSS),
+ /*1456*/ uint16(x86_xReadSlashR),
+ /*1457*/ uint16(x86_xArgXmm1),
+ /*1458*/ uint16(x86_xArgXmm2M32),
+ /*1459*/ uint16(x86_xMatch),
+ /*1460*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1488,
+ 0xF2, 1482,
+ 0x66, 1476,
+ 0x0, 1470,
+ /*1470*/ uint16(x86_xSetOp), uint16(x86_MOVUPS),
+ /*1472*/ uint16(x86_xReadSlashR),
+ /*1473*/ uint16(x86_xArgXmm2M128),
+ /*1474*/ uint16(x86_xArgXmm1),
+ /*1475*/ uint16(x86_xMatch),
+ /*1476*/ uint16(x86_xSetOp), uint16(x86_MOVUPD),
+ /*1478*/ uint16(x86_xReadSlashR),
+ /*1479*/ uint16(x86_xArgXmm2M128),
+ /*1480*/ uint16(x86_xArgXmm),
+ /*1481*/ uint16(x86_xMatch),
+ /*1482*/ uint16(x86_xSetOp), uint16(x86_MOVSD_XMM),
+ /*1484*/ uint16(x86_xReadSlashR),
+ /*1485*/ uint16(x86_xArgXmm2M64),
+ /*1486*/ uint16(x86_xArgXmm1),
+ /*1487*/ uint16(x86_xMatch),
+ /*1488*/ uint16(x86_xSetOp), uint16(x86_MOVSS),
+ /*1490*/ uint16(x86_xReadSlashR),
+ /*1491*/ uint16(x86_xArgXmm2M32),
+ /*1492*/ uint16(x86_xArgXmm),
+ /*1493*/ uint16(x86_xMatch),
+ /*1494*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1531,
+ 0xF2, 1525,
+ 0x66, 1519,
+ 0x0, 1504,
+ /*1504*/ uint16(x86_xCondIsMem), 1507, 1513,
+ /*1507*/ uint16(x86_xSetOp), uint16(x86_MOVHLPS),
+ /*1509*/ uint16(x86_xReadSlashR),
+ /*1510*/ uint16(x86_xArgXmm1),
+ /*1511*/ uint16(x86_xArgXmm2),
+ /*1512*/ uint16(x86_xMatch),
+ /*1513*/ uint16(x86_xSetOp), uint16(x86_MOVLPS),
+ /*1515*/ uint16(x86_xReadSlashR),
+ /*1516*/ uint16(x86_xArgXmm),
+ /*1517*/ uint16(x86_xArgM64),
+ /*1518*/ uint16(x86_xMatch),
+ /*1519*/ uint16(x86_xSetOp), uint16(x86_MOVLPD),
+ /*1521*/ uint16(x86_xReadSlashR),
+ /*1522*/ uint16(x86_xArgXmm),
+ /*1523*/ uint16(x86_xArgXmm2M64),
+ /*1524*/ uint16(x86_xMatch),
+ /*1525*/ uint16(x86_xSetOp), uint16(x86_MOVDDUP),
+ /*1527*/ uint16(x86_xReadSlashR),
+ /*1528*/ uint16(x86_xArgXmm1),
+ /*1529*/ uint16(x86_xArgXmm2M64),
+ /*1530*/ uint16(x86_xMatch),
+ /*1531*/ uint16(x86_xSetOp), uint16(x86_MOVSLDUP),
+ /*1533*/ uint16(x86_xReadSlashR),
+ /*1534*/ uint16(x86_xArgXmm1),
+ /*1535*/ uint16(x86_xArgXmm2M128),
+ /*1536*/ uint16(x86_xMatch),
+ /*1537*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 1549,
+ 0x0, 1543,
+ /*1543*/ uint16(x86_xSetOp), uint16(x86_MOVLPS),
+ /*1545*/ uint16(x86_xReadSlashR),
+ /*1546*/ uint16(x86_xArgM64),
+ /*1547*/ uint16(x86_xArgXmm),
+ /*1548*/ uint16(x86_xMatch),
+ /*1549*/ uint16(x86_xSetOp), uint16(x86_MOVLPD),
+ /*1551*/ uint16(x86_xReadSlashR),
+ /*1552*/ uint16(x86_xArgXmm2M64),
+ /*1553*/ uint16(x86_xArgXmm),
+ /*1554*/ uint16(x86_xMatch),
+ /*1555*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 1567,
+ 0x0, 1561,
+ /*1561*/ uint16(x86_xSetOp), uint16(x86_UNPCKLPS),
+ /*1563*/ uint16(x86_xReadSlashR),
+ /*1564*/ uint16(x86_xArgXmm1),
+ /*1565*/ uint16(x86_xArgXmm2M128),
+ /*1566*/ uint16(x86_xMatch),
+ /*1567*/ uint16(x86_xSetOp), uint16(x86_UNPCKLPD),
+ /*1569*/ uint16(x86_xReadSlashR),
+ /*1570*/ uint16(x86_xArgXmm1),
+ /*1571*/ uint16(x86_xArgXmm2M128),
+ /*1572*/ uint16(x86_xMatch),
+ /*1573*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 1585,
+ 0x0, 1579,
+ /*1579*/ uint16(x86_xSetOp), uint16(x86_UNPCKHPS),
+ /*1581*/ uint16(x86_xReadSlashR),
+ /*1582*/ uint16(x86_xArgXmm1),
+ /*1583*/ uint16(x86_xArgXmm2M128),
+ /*1584*/ uint16(x86_xMatch),
+ /*1585*/ uint16(x86_xSetOp), uint16(x86_UNPCKHPD),
+ /*1587*/ uint16(x86_xReadSlashR),
+ /*1588*/ uint16(x86_xArgXmm1),
+ /*1589*/ uint16(x86_xArgXmm2M128),
+ /*1590*/ uint16(x86_xMatch),
+ /*1591*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 1620,
+ 0x66, 1614,
+ 0x0, 1599,
+ /*1599*/ uint16(x86_xCondIsMem), 1602, 1608,
+ /*1602*/ uint16(x86_xSetOp), uint16(x86_MOVLHPS),
+ /*1604*/ uint16(x86_xReadSlashR),
+ /*1605*/ uint16(x86_xArgXmm1),
+ /*1606*/ uint16(x86_xArgXmm2),
+ /*1607*/ uint16(x86_xMatch),
+ /*1608*/ uint16(x86_xSetOp), uint16(x86_MOVHPS),
+ /*1610*/ uint16(x86_xReadSlashR),
+ /*1611*/ uint16(x86_xArgXmm),
+ /*1612*/ uint16(x86_xArgM64),
+ /*1613*/ uint16(x86_xMatch),
+ /*1614*/ uint16(x86_xSetOp), uint16(x86_MOVHPD),
+ /*1616*/ uint16(x86_xReadSlashR),
+ /*1617*/ uint16(x86_xArgXmm),
+ /*1618*/ uint16(x86_xArgXmm2M64),
+ /*1619*/ uint16(x86_xMatch),
+ /*1620*/ uint16(x86_xSetOp), uint16(x86_MOVSHDUP),
+ /*1622*/ uint16(x86_xReadSlashR),
+ /*1623*/ uint16(x86_xArgXmm1),
+ /*1624*/ uint16(x86_xArgXmm2M128),
+ /*1625*/ uint16(x86_xMatch),
+ /*1626*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 1638,
+ 0x0, 1632,
+ /*1632*/ uint16(x86_xSetOp), uint16(x86_MOVHPS),
+ /*1634*/ uint16(x86_xReadSlashR),
+ /*1635*/ uint16(x86_xArgM64),
+ /*1636*/ uint16(x86_xArgXmm),
+ /*1637*/ uint16(x86_xMatch),
+ /*1638*/ uint16(x86_xSetOp), uint16(x86_MOVHPD),
+ /*1640*/ uint16(x86_xReadSlashR),
+ /*1641*/ uint16(x86_xArgXmm2M64),
+ /*1642*/ uint16(x86_xArgXmm),
+ /*1643*/ uint16(x86_xMatch),
+ /*1644*/ uint16(x86_xCondSlashR),
+ 1653, // 0
+ 1657, // 1
+ 1661, // 2
+ 1665, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*1653*/ uint16(x86_xSetOp), uint16(x86_PREFETCHNTA),
+ /*1655*/ uint16(x86_xArgM8),
+ /*1656*/ uint16(x86_xMatch),
+ /*1657*/ uint16(x86_xSetOp), uint16(x86_PREFETCHT0),
+ /*1659*/ uint16(x86_xArgM8),
+ /*1660*/ uint16(x86_xMatch),
+ /*1661*/ uint16(x86_xSetOp), uint16(x86_PREFETCHT1),
+ /*1663*/ uint16(x86_xArgM8),
+ /*1664*/ uint16(x86_xMatch),
+ /*1665*/ uint16(x86_xSetOp), uint16(x86_PREFETCHT2),
+ /*1667*/ uint16(x86_xArgM8),
+ /*1668*/ uint16(x86_xMatch),
+ /*1669*/ uint16(x86_xCondSlashR),
+ 1678, // 0
+ 0, // 1
+ 0, // 2
+ 0, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*1678*/ uint16(x86_xCondDataSize), 1682, 1686, 0,
+ /*1682*/ uint16(x86_xSetOp), uint16(x86_NOP),
+ /*1684*/ uint16(x86_xArgRM16),
+ /*1685*/ uint16(x86_xMatch),
+ /*1686*/ uint16(x86_xSetOp), uint16(x86_NOP),
+ /*1688*/ uint16(x86_xArgRM32),
+ /*1689*/ uint16(x86_xMatch),
+ /*1690*/ uint16(x86_xCondIs64), 1693, 1699,
+ /*1693*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1695*/ uint16(x86_xReadSlashR),
+ /*1696*/ uint16(x86_xArgRmf32),
+ /*1697*/ uint16(x86_xArgCR0dashCR7),
+ /*1698*/ uint16(x86_xMatch),
+ /*1699*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1701*/ uint16(x86_xReadSlashR),
+ /*1702*/ uint16(x86_xArgRmf64),
+ /*1703*/ uint16(x86_xArgCR0dashCR7),
+ /*1704*/ uint16(x86_xMatch),
+ /*1705*/ uint16(x86_xCondIs64), 1708, 1714,
+ /*1708*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1710*/ uint16(x86_xReadSlashR),
+ /*1711*/ uint16(x86_xArgRmf32),
+ /*1712*/ uint16(x86_xArgDR0dashDR7),
+ /*1713*/ uint16(x86_xMatch),
+ /*1714*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1716*/ uint16(x86_xReadSlashR),
+ /*1717*/ uint16(x86_xArgRmf64),
+ /*1718*/ uint16(x86_xArgDR0dashDR7),
+ /*1719*/ uint16(x86_xMatch),
+ /*1720*/ uint16(x86_xCondIs64), 1723, 1729,
+ /*1723*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1725*/ uint16(x86_xReadSlashR),
+ /*1726*/ uint16(x86_xArgCR0dashCR7),
+ /*1727*/ uint16(x86_xArgRmf32),
+ /*1728*/ uint16(x86_xMatch),
+ /*1729*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1731*/ uint16(x86_xReadSlashR),
+ /*1732*/ uint16(x86_xArgCR0dashCR7),
+ /*1733*/ uint16(x86_xArgRmf64),
+ /*1734*/ uint16(x86_xMatch),
+ /*1735*/ uint16(x86_xCondIs64), 1738, 1744,
+ /*1738*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1740*/ uint16(x86_xReadSlashR),
+ /*1741*/ uint16(x86_xArgDR0dashDR7),
+ /*1742*/ uint16(x86_xArgRmf32),
+ /*1743*/ uint16(x86_xMatch),
+ /*1744*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1746*/ uint16(x86_xReadSlashR),
+ /*1747*/ uint16(x86_xArgDR0dashDR7),
+ /*1748*/ uint16(x86_xArgRmf64),
+ /*1749*/ uint16(x86_xMatch),
+ /*1750*/ uint16(x86_xCondIs64), 1753, 1759,
+ /*1753*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1755*/ uint16(x86_xReadSlashR),
+ /*1756*/ uint16(x86_xArgRmf32),
+ /*1757*/ uint16(x86_xArgTR0dashTR7),
+ /*1758*/ uint16(x86_xMatch),
+ /*1759*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1761*/ uint16(x86_xReadSlashR),
+ /*1762*/ uint16(x86_xArgRmf64),
+ /*1763*/ uint16(x86_xArgTR0dashTR7),
+ /*1764*/ uint16(x86_xMatch),
+ /*1765*/ uint16(x86_xCondIs64), 1768, 1774,
+ /*1768*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1770*/ uint16(x86_xReadSlashR),
+ /*1771*/ uint16(x86_xArgTR0dashTR7),
+ /*1772*/ uint16(x86_xArgRmf32),
+ /*1773*/ uint16(x86_xMatch),
+ /*1774*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*1776*/ uint16(x86_xReadSlashR),
+ /*1777*/ uint16(x86_xArgTR0dashTR7),
+ /*1778*/ uint16(x86_xArgRmf64),
+ /*1779*/ uint16(x86_xMatch),
+ /*1780*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 1792,
+ 0x0, 1786,
+ /*1786*/ uint16(x86_xSetOp), uint16(x86_MOVAPS),
+ /*1788*/ uint16(x86_xReadSlashR),
+ /*1789*/ uint16(x86_xArgXmm1),
+ /*1790*/ uint16(x86_xArgXmm2M128),
+ /*1791*/ uint16(x86_xMatch),
+ /*1792*/ uint16(x86_xSetOp), uint16(x86_MOVAPD),
+ /*1794*/ uint16(x86_xReadSlashR),
+ /*1795*/ uint16(x86_xArgXmm1),
+ /*1796*/ uint16(x86_xArgXmm2M128),
+ /*1797*/ uint16(x86_xMatch),
+ /*1798*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 1810,
+ 0x0, 1804,
+ /*1804*/ uint16(x86_xSetOp), uint16(x86_MOVAPS),
+ /*1806*/ uint16(x86_xReadSlashR),
+ /*1807*/ uint16(x86_xArgXmm2M128),
+ /*1808*/ uint16(x86_xArgXmm1),
+ /*1809*/ uint16(x86_xMatch),
+ /*1810*/ uint16(x86_xSetOp), uint16(x86_MOVAPD),
+ /*1812*/ uint16(x86_xReadSlashR),
+ /*1813*/ uint16(x86_xArgXmm2M128),
+ /*1814*/ uint16(x86_xArgXmm1),
+ /*1815*/ uint16(x86_xMatch),
+ /*1816*/ uint16(x86_xCondIs64), 1819, 1873,
+ /*1819*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1857,
+ 0xF2, 1841,
+ 0x66, 1835,
+ 0x0, 1829,
+ /*1829*/ uint16(x86_xSetOp), uint16(x86_CVTPI2PS),
+ /*1831*/ uint16(x86_xReadSlashR),
+ /*1832*/ uint16(x86_xArgXmm),
+ /*1833*/ uint16(x86_xArgMmM64),
+ /*1834*/ uint16(x86_xMatch),
+ /*1835*/ uint16(x86_xSetOp), uint16(x86_CVTPI2PD),
+ /*1837*/ uint16(x86_xReadSlashR),
+ /*1838*/ uint16(x86_xArgXmm),
+ /*1839*/ uint16(x86_xArgMmM64),
+ /*1840*/ uint16(x86_xMatch),
+ /*1841*/ uint16(x86_xCondDataSize), 1845, 1851, 0,
+ /*1845*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SD),
+ /*1847*/ uint16(x86_xReadSlashR),
+ /*1848*/ uint16(x86_xArgXmm),
+ /*1849*/ uint16(x86_xArgRM32),
+ /*1850*/ uint16(x86_xMatch),
+ /*1851*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SD),
+ /*1853*/ uint16(x86_xReadSlashR),
+ /*1854*/ uint16(x86_xArgXmm),
+ /*1855*/ uint16(x86_xArgRM32),
+ /*1856*/ uint16(x86_xMatch),
+ /*1857*/ uint16(x86_xCondDataSize), 1861, 1867, 0,
+ /*1861*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SS),
+ /*1863*/ uint16(x86_xReadSlashR),
+ /*1864*/ uint16(x86_xArgXmm),
+ /*1865*/ uint16(x86_xArgRM32),
+ /*1866*/ uint16(x86_xMatch),
+ /*1867*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SS),
+ /*1869*/ uint16(x86_xReadSlashR),
+ /*1870*/ uint16(x86_xArgXmm),
+ /*1871*/ uint16(x86_xArgRM32),
+ /*1872*/ uint16(x86_xMatch),
+ /*1873*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1893,
+ 0xF2, 1883,
+ 0x66, 1835,
+ 0x0, 1829,
+ /*1883*/ uint16(x86_xCondDataSize), 1845, 1851, 1887,
+ /*1887*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SD),
+ /*1889*/ uint16(x86_xReadSlashR),
+ /*1890*/ uint16(x86_xArgXmm),
+ /*1891*/ uint16(x86_xArgRM64),
+ /*1892*/ uint16(x86_xMatch),
+ /*1893*/ uint16(x86_xCondDataSize), 1861, 1867, 1897,
+ /*1897*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SS),
+ /*1899*/ uint16(x86_xReadSlashR),
+ /*1900*/ uint16(x86_xArgXmm),
+ /*1901*/ uint16(x86_xArgRM64),
+ /*1902*/ uint16(x86_xMatch),
+ /*1903*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1931,
+ 0xF2, 1925,
+ 0x66, 1919,
+ 0x0, 1913,
+ /*1913*/ uint16(x86_xSetOp), uint16(x86_MOVNTPS),
+ /*1915*/ uint16(x86_xReadSlashR),
+ /*1916*/ uint16(x86_xArgM128),
+ /*1917*/ uint16(x86_xArgXmm),
+ /*1918*/ uint16(x86_xMatch),
+ /*1919*/ uint16(x86_xSetOp), uint16(x86_MOVNTPD),
+ /*1921*/ uint16(x86_xReadSlashR),
+ /*1922*/ uint16(x86_xArgM128),
+ /*1923*/ uint16(x86_xArgXmm),
+ /*1924*/ uint16(x86_xMatch),
+ /*1925*/ uint16(x86_xSetOp), uint16(x86_MOVNTSD),
+ /*1927*/ uint16(x86_xReadSlashR),
+ /*1928*/ uint16(x86_xArgM64),
+ /*1929*/ uint16(x86_xArgXmm),
+ /*1930*/ uint16(x86_xMatch),
+ /*1931*/ uint16(x86_xSetOp), uint16(x86_MOVNTSS),
+ /*1933*/ uint16(x86_xReadSlashR),
+ /*1934*/ uint16(x86_xArgM32),
+ /*1935*/ uint16(x86_xArgXmm),
+ /*1936*/ uint16(x86_xMatch),
+ /*1937*/ uint16(x86_xCondIs64), 1940, 1994,
+ /*1940*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 1978,
+ 0xF2, 1962,
+ 0x66, 1956,
+ 0x0, 1950,
+ /*1950*/ uint16(x86_xSetOp), uint16(x86_CVTTPS2PI),
+ /*1952*/ uint16(x86_xReadSlashR),
+ /*1953*/ uint16(x86_xArgMm),
+ /*1954*/ uint16(x86_xArgXmmM64),
+ /*1955*/ uint16(x86_xMatch),
+ /*1956*/ uint16(x86_xSetOp), uint16(x86_CVTTPD2PI),
+ /*1958*/ uint16(x86_xReadSlashR),
+ /*1959*/ uint16(x86_xArgMm),
+ /*1960*/ uint16(x86_xArgXmmM128),
+ /*1961*/ uint16(x86_xMatch),
+ /*1962*/ uint16(x86_xCondDataSize), 1966, 1972, 0,
+ /*1966*/ uint16(x86_xSetOp), uint16(x86_CVTTSD2SI),
+ /*1968*/ uint16(x86_xReadSlashR),
+ /*1969*/ uint16(x86_xArgR32),
+ /*1970*/ uint16(x86_xArgXmmM64),
+ /*1971*/ uint16(x86_xMatch),
+ /*1972*/ uint16(x86_xSetOp), uint16(x86_CVTTSD2SI),
+ /*1974*/ uint16(x86_xReadSlashR),
+ /*1975*/ uint16(x86_xArgR32),
+ /*1976*/ uint16(x86_xArgXmmM64),
+ /*1977*/ uint16(x86_xMatch),
+ /*1978*/ uint16(x86_xCondDataSize), 1982, 1988, 0,
+ /*1982*/ uint16(x86_xSetOp), uint16(x86_CVTTSS2SI),
+ /*1984*/ uint16(x86_xReadSlashR),
+ /*1985*/ uint16(x86_xArgR32),
+ /*1986*/ uint16(x86_xArgXmmM32),
+ /*1987*/ uint16(x86_xMatch),
+ /*1988*/ uint16(x86_xSetOp), uint16(x86_CVTTSS2SI),
+ /*1990*/ uint16(x86_xReadSlashR),
+ /*1991*/ uint16(x86_xArgR32),
+ /*1992*/ uint16(x86_xArgXmmM32),
+ /*1993*/ uint16(x86_xMatch),
+ /*1994*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 2014,
+ 0xF2, 2004,
+ 0x66, 1956,
+ 0x0, 1950,
+ /*2004*/ uint16(x86_xCondDataSize), 1966, 1972, 2008,
+ /*2008*/ uint16(x86_xSetOp), uint16(x86_CVTTSD2SI),
+ /*2010*/ uint16(x86_xReadSlashR),
+ /*2011*/ uint16(x86_xArgR64),
+ /*2012*/ uint16(x86_xArgXmmM64),
+ /*2013*/ uint16(x86_xMatch),
+ /*2014*/ uint16(x86_xCondDataSize), 1982, 1988, 2018,
+ /*2018*/ uint16(x86_xSetOp), uint16(x86_CVTTSS2SI),
+ /*2020*/ uint16(x86_xReadSlashR),
+ /*2021*/ uint16(x86_xArgR64),
+ /*2022*/ uint16(x86_xArgXmmM32),
+ /*2023*/ uint16(x86_xMatch),
+ /*2024*/ uint16(x86_xCondIs64), 2027, 2081,
+ /*2027*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 2065,
+ 0xF2, 2049,
+ 0x66, 2043,
+ 0x0, 2037,
+ /*2037*/ uint16(x86_xSetOp), uint16(x86_CVTPS2PI),
+ /*2039*/ uint16(x86_xReadSlashR),
+ /*2040*/ uint16(x86_xArgMm),
+ /*2041*/ uint16(x86_xArgXmmM64),
+ /*2042*/ uint16(x86_xMatch),
+ /*2043*/ uint16(x86_xSetOp), uint16(x86_CVTPD2PI),
+ /*2045*/ uint16(x86_xReadSlashR),
+ /*2046*/ uint16(x86_xArgMm),
+ /*2047*/ uint16(x86_xArgXmmM128),
+ /*2048*/ uint16(x86_xMatch),
+ /*2049*/ uint16(x86_xCondDataSize), 2053, 2059, 0,
+ /*2053*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SI),
+ /*2055*/ uint16(x86_xReadSlashR),
+ /*2056*/ uint16(x86_xArgR32),
+ /*2057*/ uint16(x86_xArgXmmM64),
+ /*2058*/ uint16(x86_xMatch),
+ /*2059*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SI),
+ /*2061*/ uint16(x86_xReadSlashR),
+ /*2062*/ uint16(x86_xArgR32),
+ /*2063*/ uint16(x86_xArgXmmM64),
+ /*2064*/ uint16(x86_xMatch),
+ /*2065*/ uint16(x86_xCondDataSize), 2069, 2075, 0,
+ /*2069*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SI),
+ /*2071*/ uint16(x86_xReadSlashR),
+ /*2072*/ uint16(x86_xArgR32),
+ /*2073*/ uint16(x86_xArgXmmM32),
+ /*2074*/ uint16(x86_xMatch),
+ /*2075*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SI),
+ /*2077*/ uint16(x86_xReadSlashR),
+ /*2078*/ uint16(x86_xArgR32),
+ /*2079*/ uint16(x86_xArgXmmM32),
+ /*2080*/ uint16(x86_xMatch),
+ /*2081*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 2101,
+ 0xF2, 2091,
+ 0x66, 2043,
+ 0x0, 2037,
+ /*2091*/ uint16(x86_xCondDataSize), 2053, 2059, 2095,
+ /*2095*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SI),
+ /*2097*/ uint16(x86_xReadSlashR),
+ /*2098*/ uint16(x86_xArgR64),
+ /*2099*/ uint16(x86_xArgXmmM64),
+ /*2100*/ uint16(x86_xMatch),
+ /*2101*/ uint16(x86_xCondDataSize), 2069, 2075, 2105,
+ /*2105*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SI),
+ /*2107*/ uint16(x86_xReadSlashR),
+ /*2108*/ uint16(x86_xArgR64),
+ /*2109*/ uint16(x86_xArgXmmM32),
+ /*2110*/ uint16(x86_xMatch),
+ /*2111*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2123,
+ 0x0, 2117,
+ /*2117*/ uint16(x86_xSetOp), uint16(x86_UCOMISS),
+ /*2119*/ uint16(x86_xReadSlashR),
+ /*2120*/ uint16(x86_xArgXmm1),
+ /*2121*/ uint16(x86_xArgXmm2M32),
+ /*2122*/ uint16(x86_xMatch),
+ /*2123*/ uint16(x86_xSetOp), uint16(x86_UCOMISD),
+ /*2125*/ uint16(x86_xReadSlashR),
+ /*2126*/ uint16(x86_xArgXmm1),
+ /*2127*/ uint16(x86_xArgXmm2M64),
+ /*2128*/ uint16(x86_xMatch),
+ /*2129*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2141,
+ 0x0, 2135,
+ /*2135*/ uint16(x86_xSetOp), uint16(x86_COMISS),
+ /*2137*/ uint16(x86_xReadSlashR),
+ /*2138*/ uint16(x86_xArgXmm1),
+ /*2139*/ uint16(x86_xArgXmm2M32),
+ /*2140*/ uint16(x86_xMatch),
+ /*2141*/ uint16(x86_xSetOp), uint16(x86_COMISD),
+ /*2143*/ uint16(x86_xReadSlashR),
+ /*2144*/ uint16(x86_xArgXmm1),
+ /*2145*/ uint16(x86_xArgXmm2M64),
+ /*2146*/ uint16(x86_xMatch),
+ /*2147*/ uint16(x86_xSetOp), uint16(x86_WRMSR),
+ /*2149*/ uint16(x86_xMatch),
+ /*2150*/ uint16(x86_xSetOp), uint16(x86_RDTSC),
+ /*2152*/ uint16(x86_xMatch),
+ /*2153*/ uint16(x86_xSetOp), uint16(x86_RDMSR),
+ /*2155*/ uint16(x86_xMatch),
+ /*2156*/ uint16(x86_xSetOp), uint16(x86_RDPMC),
+ /*2158*/ uint16(x86_xMatch),
+ /*2159*/ uint16(x86_xSetOp), uint16(x86_SYSENTER),
+ /*2161*/ uint16(x86_xMatch),
+ /*2162*/ uint16(x86_xCondDataSize), 2166, 2166, 2169,
+ /*2166*/ uint16(x86_xSetOp), uint16(x86_SYSEXIT),
+ /*2168*/ uint16(x86_xMatch),
+ /*2169*/ uint16(x86_xSetOp), uint16(x86_SYSEXIT),
+ /*2171*/ uint16(x86_xMatch),
+ /*2172*/ uint16(x86_xCondByte), 54,
+ 0x00, 2283,
+ 0x01, 2301,
+ 0x02, 2319,
+ 0x03, 2337,
+ 0x04, 2355,
+ 0x05, 2373,
+ 0x06, 2391,
+ 0x07, 2409,
+ 0x08, 2427,
+ 0x09, 2445,
+ 0x0A, 2463,
+ 0x0B, 2481,
+ 0x10, 2499,
+ 0x14, 2510,
+ 0x15, 2521,
+ 0x17, 2532,
+ 0x1C, 2542,
+ 0x1D, 2560,
+ 0x1E, 2578,
+ 0x20, 2596,
+ 0x21, 2606,
+ 0x22, 2616,
+ 0x23, 2626,
+ 0x24, 2636,
+ 0x25, 2646,
+ 0x28, 2656,
+ 0x29, 2666,
+ 0x2A, 2676,
+ 0x2B, 2686,
+ 0x30, 2696,
+ 0x31, 2706,
+ 0x32, 2716,
+ 0x33, 2726,
+ 0x34, 2736,
+ 0x35, 2746,
+ 0x37, 2756,
+ 0x38, 2766,
+ 0x39, 2776,
+ 0x3A, 2786,
+ 0x3B, 2796,
+ 0x3C, 2806,
+ 0x3D, 2816,
+ 0x3E, 2826,
+ 0x3F, 2836,
+ 0x40, 2846,
+ 0x41, 2856,
+ 0x82, 2866,
+ 0xDB, 2889,
+ 0xDC, 2899,
+ 0xDD, 2909,
+ 0xDE, 2919,
+ 0xDF, 2929,
+ 0xF0, 2939,
+ 0xF1, 3006,
+ uint16(x86_xFail),
+ /*2283*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2295,
+ 0x0, 2289,
+ /*2289*/ uint16(x86_xSetOp), uint16(x86_PSHUFB),
+ /*2291*/ uint16(x86_xReadSlashR),
+ /*2292*/ uint16(x86_xArgMm1),
+ /*2293*/ uint16(x86_xArgMm2M64),
+ /*2294*/ uint16(x86_xMatch),
+ /*2295*/ uint16(x86_xSetOp), uint16(x86_PSHUFB),
+ /*2297*/ uint16(x86_xReadSlashR),
+ /*2298*/ uint16(x86_xArgXmm1),
+ /*2299*/ uint16(x86_xArgXmm2M128),
+ /*2300*/ uint16(x86_xMatch),
+ /*2301*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2313,
+ 0x0, 2307,
+ /*2307*/ uint16(x86_xSetOp), uint16(x86_PHADDW),
+ /*2309*/ uint16(x86_xReadSlashR),
+ /*2310*/ uint16(x86_xArgMm1),
+ /*2311*/ uint16(x86_xArgMm2M64),
+ /*2312*/ uint16(x86_xMatch),
+ /*2313*/ uint16(x86_xSetOp), uint16(x86_PHADDW),
+ /*2315*/ uint16(x86_xReadSlashR),
+ /*2316*/ uint16(x86_xArgXmm1),
+ /*2317*/ uint16(x86_xArgXmm2M128),
+ /*2318*/ uint16(x86_xMatch),
+ /*2319*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2331,
+ 0x0, 2325,
+ /*2325*/ uint16(x86_xSetOp), uint16(x86_PHADDD),
+ /*2327*/ uint16(x86_xReadSlashR),
+ /*2328*/ uint16(x86_xArgMm1),
+ /*2329*/ uint16(x86_xArgMm2M64),
+ /*2330*/ uint16(x86_xMatch),
+ /*2331*/ uint16(x86_xSetOp), uint16(x86_PHADDD),
+ /*2333*/ uint16(x86_xReadSlashR),
+ /*2334*/ uint16(x86_xArgXmm1),
+ /*2335*/ uint16(x86_xArgXmm2M128),
+ /*2336*/ uint16(x86_xMatch),
+ /*2337*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2349,
+ 0x0, 2343,
+ /*2343*/ uint16(x86_xSetOp), uint16(x86_PHADDSW),
+ /*2345*/ uint16(x86_xReadSlashR),
+ /*2346*/ uint16(x86_xArgMm1),
+ /*2347*/ uint16(x86_xArgMm2M64),
+ /*2348*/ uint16(x86_xMatch),
+ /*2349*/ uint16(x86_xSetOp), uint16(x86_PHADDSW),
+ /*2351*/ uint16(x86_xReadSlashR),
+ /*2352*/ uint16(x86_xArgXmm1),
+ /*2353*/ uint16(x86_xArgXmm2M128),
+ /*2354*/ uint16(x86_xMatch),
+ /*2355*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2367,
+ 0x0, 2361,
+ /*2361*/ uint16(x86_xSetOp), uint16(x86_PMADDUBSW),
+ /*2363*/ uint16(x86_xReadSlashR),
+ /*2364*/ uint16(x86_xArgMm1),
+ /*2365*/ uint16(x86_xArgMm2M64),
+ /*2366*/ uint16(x86_xMatch),
+ /*2367*/ uint16(x86_xSetOp), uint16(x86_PMADDUBSW),
+ /*2369*/ uint16(x86_xReadSlashR),
+ /*2370*/ uint16(x86_xArgXmm1),
+ /*2371*/ uint16(x86_xArgXmm2M128),
+ /*2372*/ uint16(x86_xMatch),
+ /*2373*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2385,
+ 0x0, 2379,
+ /*2379*/ uint16(x86_xSetOp), uint16(x86_PHSUBW),
+ /*2381*/ uint16(x86_xReadSlashR),
+ /*2382*/ uint16(x86_xArgMm1),
+ /*2383*/ uint16(x86_xArgMm2M64),
+ /*2384*/ uint16(x86_xMatch),
+ /*2385*/ uint16(x86_xSetOp), uint16(x86_PHSUBW),
+ /*2387*/ uint16(x86_xReadSlashR),
+ /*2388*/ uint16(x86_xArgXmm1),
+ /*2389*/ uint16(x86_xArgXmm2M128),
+ /*2390*/ uint16(x86_xMatch),
+ /*2391*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2403,
+ 0x0, 2397,
+ /*2397*/ uint16(x86_xSetOp), uint16(x86_PHSUBD),
+ /*2399*/ uint16(x86_xReadSlashR),
+ /*2400*/ uint16(x86_xArgMm1),
+ /*2401*/ uint16(x86_xArgMm2M64),
+ /*2402*/ uint16(x86_xMatch),
+ /*2403*/ uint16(x86_xSetOp), uint16(x86_PHSUBD),
+ /*2405*/ uint16(x86_xReadSlashR),
+ /*2406*/ uint16(x86_xArgXmm1),
+ /*2407*/ uint16(x86_xArgXmm2M128),
+ /*2408*/ uint16(x86_xMatch),
+ /*2409*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2421,
+ 0x0, 2415,
+ /*2415*/ uint16(x86_xSetOp), uint16(x86_PHSUBSW),
+ /*2417*/ uint16(x86_xReadSlashR),
+ /*2418*/ uint16(x86_xArgMm1),
+ /*2419*/ uint16(x86_xArgMm2M64),
+ /*2420*/ uint16(x86_xMatch),
+ /*2421*/ uint16(x86_xSetOp), uint16(x86_PHSUBSW),
+ /*2423*/ uint16(x86_xReadSlashR),
+ /*2424*/ uint16(x86_xArgXmm1),
+ /*2425*/ uint16(x86_xArgXmm2M128),
+ /*2426*/ uint16(x86_xMatch),
+ /*2427*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2439,
+ 0x0, 2433,
+ /*2433*/ uint16(x86_xSetOp), uint16(x86_PSIGNB),
+ /*2435*/ uint16(x86_xReadSlashR),
+ /*2436*/ uint16(x86_xArgMm1),
+ /*2437*/ uint16(x86_xArgMm2M64),
+ /*2438*/ uint16(x86_xMatch),
+ /*2439*/ uint16(x86_xSetOp), uint16(x86_PSIGNB),
+ /*2441*/ uint16(x86_xReadSlashR),
+ /*2442*/ uint16(x86_xArgXmm1),
+ /*2443*/ uint16(x86_xArgXmm2M128),
+ /*2444*/ uint16(x86_xMatch),
+ /*2445*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2457,
+ 0x0, 2451,
+ /*2451*/ uint16(x86_xSetOp), uint16(x86_PSIGNW),
+ /*2453*/ uint16(x86_xReadSlashR),
+ /*2454*/ uint16(x86_xArgMm1),
+ /*2455*/ uint16(x86_xArgMm2M64),
+ /*2456*/ uint16(x86_xMatch),
+ /*2457*/ uint16(x86_xSetOp), uint16(x86_PSIGNW),
+ /*2459*/ uint16(x86_xReadSlashR),
+ /*2460*/ uint16(x86_xArgXmm1),
+ /*2461*/ uint16(x86_xArgXmm2M128),
+ /*2462*/ uint16(x86_xMatch),
+ /*2463*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2475,
+ 0x0, 2469,
+ /*2469*/ uint16(x86_xSetOp), uint16(x86_PSIGND),
+ /*2471*/ uint16(x86_xReadSlashR),
+ /*2472*/ uint16(x86_xArgMm1),
+ /*2473*/ uint16(x86_xArgMm2M64),
+ /*2474*/ uint16(x86_xMatch),
+ /*2475*/ uint16(x86_xSetOp), uint16(x86_PSIGND),
+ /*2477*/ uint16(x86_xReadSlashR),
+ /*2478*/ uint16(x86_xArgXmm1),
+ /*2479*/ uint16(x86_xArgXmm2M128),
+ /*2480*/ uint16(x86_xMatch),
+ /*2481*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2493,
+ 0x0, 2487,
+ /*2487*/ uint16(x86_xSetOp), uint16(x86_PMULHRSW),
+ /*2489*/ uint16(x86_xReadSlashR),
+ /*2490*/ uint16(x86_xArgMm1),
+ /*2491*/ uint16(x86_xArgMm2M64),
+ /*2492*/ uint16(x86_xMatch),
+ /*2493*/ uint16(x86_xSetOp), uint16(x86_PMULHRSW),
+ /*2495*/ uint16(x86_xReadSlashR),
+ /*2496*/ uint16(x86_xArgXmm1),
+ /*2497*/ uint16(x86_xArgXmm2M128),
+ /*2498*/ uint16(x86_xMatch),
+ /*2499*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2503,
+ /*2503*/ uint16(x86_xSetOp), uint16(x86_PBLENDVB),
+ /*2505*/ uint16(x86_xReadSlashR),
+ /*2506*/ uint16(x86_xArgXmm1),
+ /*2507*/ uint16(x86_xArgXmm2M128),
+ /*2508*/ uint16(x86_xArgXMM0),
+ /*2509*/ uint16(x86_xMatch),
+ /*2510*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2514,
+ /*2514*/ uint16(x86_xSetOp), uint16(x86_BLENDVPS),
+ /*2516*/ uint16(x86_xReadSlashR),
+ /*2517*/ uint16(x86_xArgXmm1),
+ /*2518*/ uint16(x86_xArgXmm2M128),
+ /*2519*/ uint16(x86_xArgXMM0),
+ /*2520*/ uint16(x86_xMatch),
+ /*2521*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2525,
+ /*2525*/ uint16(x86_xSetOp), uint16(x86_BLENDVPD),
+ /*2527*/ uint16(x86_xReadSlashR),
+ /*2528*/ uint16(x86_xArgXmm1),
+ /*2529*/ uint16(x86_xArgXmm2M128),
+ /*2530*/ uint16(x86_xArgXMM0),
+ /*2531*/ uint16(x86_xMatch),
+ /*2532*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2536,
+ /*2536*/ uint16(x86_xSetOp), uint16(x86_PTEST),
+ /*2538*/ uint16(x86_xReadSlashR),
+ /*2539*/ uint16(x86_xArgXmm1),
+ /*2540*/ uint16(x86_xArgXmm2M128),
+ /*2541*/ uint16(x86_xMatch),
+ /*2542*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2554,
+ 0x0, 2548,
+ /*2548*/ uint16(x86_xSetOp), uint16(x86_PABSB),
+ /*2550*/ uint16(x86_xReadSlashR),
+ /*2551*/ uint16(x86_xArgMm1),
+ /*2552*/ uint16(x86_xArgMm2M64),
+ /*2553*/ uint16(x86_xMatch),
+ /*2554*/ uint16(x86_xSetOp), uint16(x86_PABSB),
+ /*2556*/ uint16(x86_xReadSlashR),
+ /*2557*/ uint16(x86_xArgXmm1),
+ /*2558*/ uint16(x86_xArgXmm2M128),
+ /*2559*/ uint16(x86_xMatch),
+ /*2560*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2572,
+ 0x0, 2566,
+ /*2566*/ uint16(x86_xSetOp), uint16(x86_PABSW),
+ /*2568*/ uint16(x86_xReadSlashR),
+ /*2569*/ uint16(x86_xArgMm1),
+ /*2570*/ uint16(x86_xArgMm2M64),
+ /*2571*/ uint16(x86_xMatch),
+ /*2572*/ uint16(x86_xSetOp), uint16(x86_PABSW),
+ /*2574*/ uint16(x86_xReadSlashR),
+ /*2575*/ uint16(x86_xArgXmm1),
+ /*2576*/ uint16(x86_xArgXmm2M128),
+ /*2577*/ uint16(x86_xMatch),
+ /*2578*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 2590,
+ 0x0, 2584,
+ /*2584*/ uint16(x86_xSetOp), uint16(x86_PABSD),
+ /*2586*/ uint16(x86_xReadSlashR),
+ /*2587*/ uint16(x86_xArgMm1),
+ /*2588*/ uint16(x86_xArgMm2M64),
+ /*2589*/ uint16(x86_xMatch),
+ /*2590*/ uint16(x86_xSetOp), uint16(x86_PABSD),
+ /*2592*/ uint16(x86_xReadSlashR),
+ /*2593*/ uint16(x86_xArgXmm1),
+ /*2594*/ uint16(x86_xArgXmm2M128),
+ /*2595*/ uint16(x86_xMatch),
+ /*2596*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2600,
+ /*2600*/ uint16(x86_xSetOp), uint16(x86_PMOVSXBW),
+ /*2602*/ uint16(x86_xReadSlashR),
+ /*2603*/ uint16(x86_xArgXmm1),
+ /*2604*/ uint16(x86_xArgXmm2M64),
+ /*2605*/ uint16(x86_xMatch),
+ /*2606*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2610,
+ /*2610*/ uint16(x86_xSetOp), uint16(x86_PMOVSXBD),
+ /*2612*/ uint16(x86_xReadSlashR),
+ /*2613*/ uint16(x86_xArgXmm1),
+ /*2614*/ uint16(x86_xArgXmm2M32),
+ /*2615*/ uint16(x86_xMatch),
+ /*2616*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2620,
+ /*2620*/ uint16(x86_xSetOp), uint16(x86_PMOVSXBQ),
+ /*2622*/ uint16(x86_xReadSlashR),
+ /*2623*/ uint16(x86_xArgXmm1),
+ /*2624*/ uint16(x86_xArgXmm2M16),
+ /*2625*/ uint16(x86_xMatch),
+ /*2626*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2630,
+ /*2630*/ uint16(x86_xSetOp), uint16(x86_PMOVSXWD),
+ /*2632*/ uint16(x86_xReadSlashR),
+ /*2633*/ uint16(x86_xArgXmm1),
+ /*2634*/ uint16(x86_xArgXmm2M64),
+ /*2635*/ uint16(x86_xMatch),
+ /*2636*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2640,
+ /*2640*/ uint16(x86_xSetOp), uint16(x86_PMOVSXWQ),
+ /*2642*/ uint16(x86_xReadSlashR),
+ /*2643*/ uint16(x86_xArgXmm1),
+ /*2644*/ uint16(x86_xArgXmm2M32),
+ /*2645*/ uint16(x86_xMatch),
+ /*2646*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2650,
+ /*2650*/ uint16(x86_xSetOp), uint16(x86_PMOVSXDQ),
+ /*2652*/ uint16(x86_xReadSlashR),
+ /*2653*/ uint16(x86_xArgXmm1),
+ /*2654*/ uint16(x86_xArgXmm2M64),
+ /*2655*/ uint16(x86_xMatch),
+ /*2656*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2660,
+ /*2660*/ uint16(x86_xSetOp), uint16(x86_PMULDQ),
+ /*2662*/ uint16(x86_xReadSlashR),
+ /*2663*/ uint16(x86_xArgXmm1),
+ /*2664*/ uint16(x86_xArgXmm2M128),
+ /*2665*/ uint16(x86_xMatch),
+ /*2666*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2670,
+ /*2670*/ uint16(x86_xSetOp), uint16(x86_PCMPEQQ),
+ /*2672*/ uint16(x86_xReadSlashR),
+ /*2673*/ uint16(x86_xArgXmm1),
+ /*2674*/ uint16(x86_xArgXmm2M128),
+ /*2675*/ uint16(x86_xMatch),
+ /*2676*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2680,
+ /*2680*/ uint16(x86_xSetOp), uint16(x86_MOVNTDQA),
+ /*2682*/ uint16(x86_xReadSlashR),
+ /*2683*/ uint16(x86_xArgXmm1),
+ /*2684*/ uint16(x86_xArgM128),
+ /*2685*/ uint16(x86_xMatch),
+ /*2686*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2690,
+ /*2690*/ uint16(x86_xSetOp), uint16(x86_PACKUSDW),
+ /*2692*/ uint16(x86_xReadSlashR),
+ /*2693*/ uint16(x86_xArgXmm1),
+ /*2694*/ uint16(x86_xArgXmm2M128),
+ /*2695*/ uint16(x86_xMatch),
+ /*2696*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2700,
+ /*2700*/ uint16(x86_xSetOp), uint16(x86_PMOVZXBW),
+ /*2702*/ uint16(x86_xReadSlashR),
+ /*2703*/ uint16(x86_xArgXmm1),
+ /*2704*/ uint16(x86_xArgXmm2M64),
+ /*2705*/ uint16(x86_xMatch),
+ /*2706*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2710,
+ /*2710*/ uint16(x86_xSetOp), uint16(x86_PMOVZXBD),
+ /*2712*/ uint16(x86_xReadSlashR),
+ /*2713*/ uint16(x86_xArgXmm1),
+ /*2714*/ uint16(x86_xArgXmm2M32),
+ /*2715*/ uint16(x86_xMatch),
+ /*2716*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2720,
+ /*2720*/ uint16(x86_xSetOp), uint16(x86_PMOVZXBQ),
+ /*2722*/ uint16(x86_xReadSlashR),
+ /*2723*/ uint16(x86_xArgXmm1),
+ /*2724*/ uint16(x86_xArgXmm2M16),
+ /*2725*/ uint16(x86_xMatch),
+ /*2726*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2730,
+ /*2730*/ uint16(x86_xSetOp), uint16(x86_PMOVZXWD),
+ /*2732*/ uint16(x86_xReadSlashR),
+ /*2733*/ uint16(x86_xArgXmm1),
+ /*2734*/ uint16(x86_xArgXmm2M64),
+ /*2735*/ uint16(x86_xMatch),
+ /*2736*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2740,
+ /*2740*/ uint16(x86_xSetOp), uint16(x86_PMOVZXWQ),
+ /*2742*/ uint16(x86_xReadSlashR),
+ /*2743*/ uint16(x86_xArgXmm1),
+ /*2744*/ uint16(x86_xArgXmm2M32),
+ /*2745*/ uint16(x86_xMatch),
+ /*2746*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2750,
+ /*2750*/ uint16(x86_xSetOp), uint16(x86_PMOVZXDQ),
+ /*2752*/ uint16(x86_xReadSlashR),
+ /*2753*/ uint16(x86_xArgXmm1),
+ /*2754*/ uint16(x86_xArgXmm2M64),
+ /*2755*/ uint16(x86_xMatch),
+ /*2756*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2760,
+ /*2760*/ uint16(x86_xSetOp), uint16(x86_PCMPGTQ),
+ /*2762*/ uint16(x86_xReadSlashR),
+ /*2763*/ uint16(x86_xArgXmm1),
+ /*2764*/ uint16(x86_xArgXmm2M128),
+ /*2765*/ uint16(x86_xMatch),
+ /*2766*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2770,
+ /*2770*/ uint16(x86_xSetOp), uint16(x86_PMINSB),
+ /*2772*/ uint16(x86_xReadSlashR),
+ /*2773*/ uint16(x86_xArgXmm1),
+ /*2774*/ uint16(x86_xArgXmm2M128),
+ /*2775*/ uint16(x86_xMatch),
+ /*2776*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2780,
+ /*2780*/ uint16(x86_xSetOp), uint16(x86_PMINSD),
+ /*2782*/ uint16(x86_xReadSlashR),
+ /*2783*/ uint16(x86_xArgXmm1),
+ /*2784*/ uint16(x86_xArgXmm2M128),
+ /*2785*/ uint16(x86_xMatch),
+ /*2786*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2790,
+ /*2790*/ uint16(x86_xSetOp), uint16(x86_PMINUW),
+ /*2792*/ uint16(x86_xReadSlashR),
+ /*2793*/ uint16(x86_xArgXmm1),
+ /*2794*/ uint16(x86_xArgXmm2M128),
+ /*2795*/ uint16(x86_xMatch),
+ /*2796*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2800,
+ /*2800*/ uint16(x86_xSetOp), uint16(x86_PMINUD),
+ /*2802*/ uint16(x86_xReadSlashR),
+ /*2803*/ uint16(x86_xArgXmm1),
+ /*2804*/ uint16(x86_xArgXmm2M128),
+ /*2805*/ uint16(x86_xMatch),
+ /*2806*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2810,
+ /*2810*/ uint16(x86_xSetOp), uint16(x86_PMAXSB),
+ /*2812*/ uint16(x86_xReadSlashR),
+ /*2813*/ uint16(x86_xArgXmm1),
+ /*2814*/ uint16(x86_xArgXmm2M128),
+ /*2815*/ uint16(x86_xMatch),
+ /*2816*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2820,
+ /*2820*/ uint16(x86_xSetOp), uint16(x86_PMAXSD),
+ /*2822*/ uint16(x86_xReadSlashR),
+ /*2823*/ uint16(x86_xArgXmm1),
+ /*2824*/ uint16(x86_xArgXmm2M128),
+ /*2825*/ uint16(x86_xMatch),
+ /*2826*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2830,
+ /*2830*/ uint16(x86_xSetOp), uint16(x86_PMAXUW),
+ /*2832*/ uint16(x86_xReadSlashR),
+ /*2833*/ uint16(x86_xArgXmm1),
+ /*2834*/ uint16(x86_xArgXmm2M128),
+ /*2835*/ uint16(x86_xMatch),
+ /*2836*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2840,
+ /*2840*/ uint16(x86_xSetOp), uint16(x86_PMAXUD),
+ /*2842*/ uint16(x86_xReadSlashR),
+ /*2843*/ uint16(x86_xArgXmm1),
+ /*2844*/ uint16(x86_xArgXmm2M128),
+ /*2845*/ uint16(x86_xMatch),
+ /*2846*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2850,
+ /*2850*/ uint16(x86_xSetOp), uint16(x86_PMULLD),
+ /*2852*/ uint16(x86_xReadSlashR),
+ /*2853*/ uint16(x86_xArgXmm1),
+ /*2854*/ uint16(x86_xArgXmm2M128),
+ /*2855*/ uint16(x86_xMatch),
+ /*2856*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2860,
+ /*2860*/ uint16(x86_xSetOp), uint16(x86_PHMINPOSUW),
+ /*2862*/ uint16(x86_xReadSlashR),
+ /*2863*/ uint16(x86_xArgXmm1),
+ /*2864*/ uint16(x86_xArgXmm2M128),
+ /*2865*/ uint16(x86_xMatch),
+ /*2866*/ uint16(x86_xCondIs64), 2869, 2879,
+ /*2869*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2873,
+ /*2873*/ uint16(x86_xSetOp), uint16(x86_INVPCID),
+ /*2875*/ uint16(x86_xReadSlashR),
+ /*2876*/ uint16(x86_xArgR32),
+ /*2877*/ uint16(x86_xArgM128),
+ /*2878*/ uint16(x86_xMatch),
+ /*2879*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2883,
+ /*2883*/ uint16(x86_xSetOp), uint16(x86_INVPCID),
+ /*2885*/ uint16(x86_xReadSlashR),
+ /*2886*/ uint16(x86_xArgR64),
+ /*2887*/ uint16(x86_xArgM128),
+ /*2888*/ uint16(x86_xMatch),
+ /*2889*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2893,
+ /*2893*/ uint16(x86_xSetOp), uint16(x86_AESIMC),
+ /*2895*/ uint16(x86_xReadSlashR),
+ /*2896*/ uint16(x86_xArgXmm1),
+ /*2897*/ uint16(x86_xArgXmm2M128),
+ /*2898*/ uint16(x86_xMatch),
+ /*2899*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2903,
+ /*2903*/ uint16(x86_xSetOp), uint16(x86_AESENC),
+ /*2905*/ uint16(x86_xReadSlashR),
+ /*2906*/ uint16(x86_xArgXmm1),
+ /*2907*/ uint16(x86_xArgXmm2M128),
+ /*2908*/ uint16(x86_xMatch),
+ /*2909*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2913,
+ /*2913*/ uint16(x86_xSetOp), uint16(x86_AESENCLAST),
+ /*2915*/ uint16(x86_xReadSlashR),
+ /*2916*/ uint16(x86_xArgXmm1),
+ /*2917*/ uint16(x86_xArgXmm2M128),
+ /*2918*/ uint16(x86_xMatch),
+ /*2919*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2923,
+ /*2923*/ uint16(x86_xSetOp), uint16(x86_AESDEC),
+ /*2925*/ uint16(x86_xReadSlashR),
+ /*2926*/ uint16(x86_xArgXmm1),
+ /*2927*/ uint16(x86_xArgXmm2M128),
+ /*2928*/ uint16(x86_xMatch),
+ /*2929*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 2933,
+ /*2933*/ uint16(x86_xSetOp), uint16(x86_AESDECLAST),
+ /*2935*/ uint16(x86_xReadSlashR),
+ /*2936*/ uint16(x86_xArgXmm1),
+ /*2937*/ uint16(x86_xArgXmm2M128),
+ /*2938*/ uint16(x86_xMatch),
+ /*2939*/ uint16(x86_xCondIs64), 2942, 2980,
+ /*2942*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 2964,
+ 0x0, 2948,
+ /*2948*/ uint16(x86_xCondDataSize), 2952, 2958, 0,
+ /*2952*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
+ /*2954*/ uint16(x86_xReadSlashR),
+ /*2955*/ uint16(x86_xArgR16),
+ /*2956*/ uint16(x86_xArgM16),
+ /*2957*/ uint16(x86_xMatch),
+ /*2958*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
+ /*2960*/ uint16(x86_xReadSlashR),
+ /*2961*/ uint16(x86_xArgR32),
+ /*2962*/ uint16(x86_xArgM32),
+ /*2963*/ uint16(x86_xMatch),
+ /*2964*/ uint16(x86_xCondDataSize), 2968, 2974, 0,
+ /*2968*/ uint16(x86_xSetOp), uint16(x86_CRC32),
+ /*2970*/ uint16(x86_xReadSlashR),
+ /*2971*/ uint16(x86_xArgR32),
+ /*2972*/ uint16(x86_xArgRM8),
+ /*2973*/ uint16(x86_xMatch),
+ /*2974*/ uint16(x86_xSetOp), uint16(x86_CRC32),
+ /*2976*/ uint16(x86_xReadSlashR),
+ /*2977*/ uint16(x86_xArgR32),
+ /*2978*/ uint16(x86_xArgRM8),
+ /*2979*/ uint16(x86_xMatch),
+ /*2980*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 2996,
+ 0x0, 2986,
+ /*2986*/ uint16(x86_xCondDataSize), 2952, 2958, 2990,
+ /*2990*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
+ /*2992*/ uint16(x86_xReadSlashR),
+ /*2993*/ uint16(x86_xArgR64),
+ /*2994*/ uint16(x86_xArgM64),
+ /*2995*/ uint16(x86_xMatch),
+ /*2996*/ uint16(x86_xCondDataSize), 2968, 2974, 3000,
+ /*3000*/ uint16(x86_xSetOp), uint16(x86_CRC32),
+ /*3002*/ uint16(x86_xReadSlashR),
+ /*3003*/ uint16(x86_xArgR64),
+ /*3004*/ uint16(x86_xArgRM8),
+ /*3005*/ uint16(x86_xMatch),
+ /*3006*/ uint16(x86_xCondIs64), 3009, 3047,
+ /*3009*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 3031,
+ 0x0, 3015,
+ /*3015*/ uint16(x86_xCondDataSize), 3019, 3025, 0,
+ /*3019*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
+ /*3021*/ uint16(x86_xReadSlashR),
+ /*3022*/ uint16(x86_xArgM16),
+ /*3023*/ uint16(x86_xArgR16),
+ /*3024*/ uint16(x86_xMatch),
+ /*3025*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
+ /*3027*/ uint16(x86_xReadSlashR),
+ /*3028*/ uint16(x86_xArgM32),
+ /*3029*/ uint16(x86_xArgR32),
+ /*3030*/ uint16(x86_xMatch),
+ /*3031*/ uint16(x86_xCondDataSize), 3035, 3041, 0,
+ /*3035*/ uint16(x86_xSetOp), uint16(x86_CRC32),
+ /*3037*/ uint16(x86_xReadSlashR),
+ /*3038*/ uint16(x86_xArgR32),
+ /*3039*/ uint16(x86_xArgRM16),
+ /*3040*/ uint16(x86_xMatch),
+ /*3041*/ uint16(x86_xSetOp), uint16(x86_CRC32),
+ /*3043*/ uint16(x86_xReadSlashR),
+ /*3044*/ uint16(x86_xArgR32),
+ /*3045*/ uint16(x86_xArgRM32),
+ /*3046*/ uint16(x86_xMatch),
+ /*3047*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 3063,
+ 0x0, 3053,
+ /*3053*/ uint16(x86_xCondDataSize), 3019, 3025, 3057,
+ /*3057*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
+ /*3059*/ uint16(x86_xReadSlashR),
+ /*3060*/ uint16(x86_xArgM64),
+ /*3061*/ uint16(x86_xArgR64),
+ /*3062*/ uint16(x86_xMatch),
+ /*3063*/ uint16(x86_xCondDataSize), 3035, 3041, 3067,
+ /*3067*/ uint16(x86_xSetOp), uint16(x86_CRC32),
+ /*3069*/ uint16(x86_xReadSlashR),
+ /*3070*/ uint16(x86_xArgR64),
+ /*3071*/ uint16(x86_xArgRM64),
+ /*3072*/ uint16(x86_xMatch),
+ /*3073*/ uint16(x86_xCondByte), 24,
+ 0x08, 3124,
+ 0x09, 3136,
+ 0x0A, 3148,
+ 0x0B, 3160,
+ 0x0C, 3172,
+ 0x0D, 3184,
+ 0x0E, 3196,
+ 0x0F, 3208,
+ 0x14, 3230,
+ 0x15, 3242,
+ 0x16, 3254,
+ 0x17, 3297,
+ 0x20, 3309,
+ 0x21, 3321,
+ 0x22, 3333,
+ 0x40, 3376,
+ 0x41, 3388,
+ 0x42, 3400,
+ 0x44, 3412,
+ 0x60, 3424,
+ 0x61, 3436,
+ 0x62, 3448,
+ 0x63, 3460,
+ 0xDF, 3472,
+ uint16(x86_xFail),
+ /*3124*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3128,
+ /*3128*/ uint16(x86_xSetOp), uint16(x86_ROUNDPS),
+ /*3130*/ uint16(x86_xReadSlashR),
+ /*3131*/ uint16(x86_xReadIb),
+ /*3132*/ uint16(x86_xArgXmm1),
+ /*3133*/ uint16(x86_xArgXmm2M128),
+ /*3134*/ uint16(x86_xArgImm8u),
+ /*3135*/ uint16(x86_xMatch),
+ /*3136*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3140,
+ /*3140*/ uint16(x86_xSetOp), uint16(x86_ROUNDPD),
+ /*3142*/ uint16(x86_xReadSlashR),
+ /*3143*/ uint16(x86_xReadIb),
+ /*3144*/ uint16(x86_xArgXmm1),
+ /*3145*/ uint16(x86_xArgXmm2M128),
+ /*3146*/ uint16(x86_xArgImm8u),
+ /*3147*/ uint16(x86_xMatch),
+ /*3148*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3152,
+ /*3152*/ uint16(x86_xSetOp), uint16(x86_ROUNDSS),
+ /*3154*/ uint16(x86_xReadSlashR),
+ /*3155*/ uint16(x86_xReadIb),
+ /*3156*/ uint16(x86_xArgXmm1),
+ /*3157*/ uint16(x86_xArgXmm2M32),
+ /*3158*/ uint16(x86_xArgImm8u),
+ /*3159*/ uint16(x86_xMatch),
+ /*3160*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3164,
+ /*3164*/ uint16(x86_xSetOp), uint16(x86_ROUNDSD),
+ /*3166*/ uint16(x86_xReadSlashR),
+ /*3167*/ uint16(x86_xReadIb),
+ /*3168*/ uint16(x86_xArgXmm1),
+ /*3169*/ uint16(x86_xArgXmm2M64),
+ /*3170*/ uint16(x86_xArgImm8u),
+ /*3171*/ uint16(x86_xMatch),
+ /*3172*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3176,
+ /*3176*/ uint16(x86_xSetOp), uint16(x86_BLENDPS),
+ /*3178*/ uint16(x86_xReadSlashR),
+ /*3179*/ uint16(x86_xReadIb),
+ /*3180*/ uint16(x86_xArgXmm1),
+ /*3181*/ uint16(x86_xArgXmm2M128),
+ /*3182*/ uint16(x86_xArgImm8u),
+ /*3183*/ uint16(x86_xMatch),
+ /*3184*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3188,
+ /*3188*/ uint16(x86_xSetOp), uint16(x86_BLENDPD),
+ /*3190*/ uint16(x86_xReadSlashR),
+ /*3191*/ uint16(x86_xReadIb),
+ /*3192*/ uint16(x86_xArgXmm1),
+ /*3193*/ uint16(x86_xArgXmm2M128),
+ /*3194*/ uint16(x86_xArgImm8u),
+ /*3195*/ uint16(x86_xMatch),
+ /*3196*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3200,
+ /*3200*/ uint16(x86_xSetOp), uint16(x86_PBLENDW),
+ /*3202*/ uint16(x86_xReadSlashR),
+ /*3203*/ uint16(x86_xReadIb),
+ /*3204*/ uint16(x86_xArgXmm1),
+ /*3205*/ uint16(x86_xArgXmm2M128),
+ /*3206*/ uint16(x86_xArgImm8u),
+ /*3207*/ uint16(x86_xMatch),
+ /*3208*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 3222,
+ 0x0, 3214,
+ /*3214*/ uint16(x86_xSetOp), uint16(x86_PALIGNR),
+ /*3216*/ uint16(x86_xReadSlashR),
+ /*3217*/ uint16(x86_xReadIb),
+ /*3218*/ uint16(x86_xArgMm1),
+ /*3219*/ uint16(x86_xArgMm2M64),
+ /*3220*/ uint16(x86_xArgImm8u),
+ /*3221*/ uint16(x86_xMatch),
+ /*3222*/ uint16(x86_xSetOp), uint16(x86_PALIGNR),
+ /*3224*/ uint16(x86_xReadSlashR),
+ /*3225*/ uint16(x86_xReadIb),
+ /*3226*/ uint16(x86_xArgXmm1),
+ /*3227*/ uint16(x86_xArgXmm2M128),
+ /*3228*/ uint16(x86_xArgImm8u),
+ /*3229*/ uint16(x86_xMatch),
+ /*3230*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3234,
+ /*3234*/ uint16(x86_xSetOp), uint16(x86_PEXTRB),
+ /*3236*/ uint16(x86_xReadSlashR),
+ /*3237*/ uint16(x86_xReadIb),
+ /*3238*/ uint16(x86_xArgR32M8),
+ /*3239*/ uint16(x86_xArgXmm1),
+ /*3240*/ uint16(x86_xArgImm8u),
+ /*3241*/ uint16(x86_xMatch),
+ /*3242*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3246,
+ /*3246*/ uint16(x86_xSetOp), uint16(x86_PEXTRW),
+ /*3248*/ uint16(x86_xReadSlashR),
+ /*3249*/ uint16(x86_xReadIb),
+ /*3250*/ uint16(x86_xArgR32M16),
+ /*3251*/ uint16(x86_xArgXmm1),
+ /*3252*/ uint16(x86_xArgImm8u),
+ /*3253*/ uint16(x86_xMatch),
+ /*3254*/ uint16(x86_xCondIs64), 3257, 3281,
+ /*3257*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3261,
+ /*3261*/ uint16(x86_xCondDataSize), 3265, 3273, 0,
+ /*3265*/ uint16(x86_xSetOp), uint16(x86_PEXTRD),
+ /*3267*/ uint16(x86_xReadSlashR),
+ /*3268*/ uint16(x86_xReadIb),
+ /*3269*/ uint16(x86_xArgRM32),
+ /*3270*/ uint16(x86_xArgXmm1),
+ /*3271*/ uint16(x86_xArgImm8u),
+ /*3272*/ uint16(x86_xMatch),
+ /*3273*/ uint16(x86_xSetOp), uint16(x86_PEXTRD),
+ /*3275*/ uint16(x86_xReadSlashR),
+ /*3276*/ uint16(x86_xReadIb),
+ /*3277*/ uint16(x86_xArgRM32),
+ /*3278*/ uint16(x86_xArgXmm1),
+ /*3279*/ uint16(x86_xArgImm8u),
+ /*3280*/ uint16(x86_xMatch),
+ /*3281*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3285,
+ /*3285*/ uint16(x86_xCondDataSize), 3265, 3273, 3289,
+ /*3289*/ uint16(x86_xSetOp), uint16(x86_PEXTRQ),
+ /*3291*/ uint16(x86_xReadSlashR),
+ /*3292*/ uint16(x86_xReadIb),
+ /*3293*/ uint16(x86_xArgRM64),
+ /*3294*/ uint16(x86_xArgXmm1),
+ /*3295*/ uint16(x86_xArgImm8u),
+ /*3296*/ uint16(x86_xMatch),
+ /*3297*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3301,
+ /*3301*/ uint16(x86_xSetOp), uint16(x86_EXTRACTPS),
+ /*3303*/ uint16(x86_xReadSlashR),
+ /*3304*/ uint16(x86_xReadIb),
+ /*3305*/ uint16(x86_xArgRM32),
+ /*3306*/ uint16(x86_xArgXmm1),
+ /*3307*/ uint16(x86_xArgImm8u),
+ /*3308*/ uint16(x86_xMatch),
+ /*3309*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3313,
+ /*3313*/ uint16(x86_xSetOp), uint16(x86_PINSRB),
+ /*3315*/ uint16(x86_xReadSlashR),
+ /*3316*/ uint16(x86_xReadIb),
+ /*3317*/ uint16(x86_xArgXmm1),
+ /*3318*/ uint16(x86_xArgR32M8),
+ /*3319*/ uint16(x86_xArgImm8u),
+ /*3320*/ uint16(x86_xMatch),
+ /*3321*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3325,
+ /*3325*/ uint16(x86_xSetOp), uint16(x86_INSERTPS),
+ /*3327*/ uint16(x86_xReadSlashR),
+ /*3328*/ uint16(x86_xReadIb),
+ /*3329*/ uint16(x86_xArgXmm1),
+ /*3330*/ uint16(x86_xArgXmm2M32),
+ /*3331*/ uint16(x86_xArgImm8u),
+ /*3332*/ uint16(x86_xMatch),
+ /*3333*/ uint16(x86_xCondIs64), 3336, 3360,
+ /*3336*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3340,
+ /*3340*/ uint16(x86_xCondDataSize), 3344, 3352, 0,
+ /*3344*/ uint16(x86_xSetOp), uint16(x86_PINSRD),
+ /*3346*/ uint16(x86_xReadSlashR),
+ /*3347*/ uint16(x86_xReadIb),
+ /*3348*/ uint16(x86_xArgXmm1),
+ /*3349*/ uint16(x86_xArgRM32),
+ /*3350*/ uint16(x86_xArgImm8u),
+ /*3351*/ uint16(x86_xMatch),
+ /*3352*/ uint16(x86_xSetOp), uint16(x86_PINSRD),
+ /*3354*/ uint16(x86_xReadSlashR),
+ /*3355*/ uint16(x86_xReadIb),
+ /*3356*/ uint16(x86_xArgXmm1),
+ /*3357*/ uint16(x86_xArgRM32),
+ /*3358*/ uint16(x86_xArgImm8u),
+ /*3359*/ uint16(x86_xMatch),
+ /*3360*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3364,
+ /*3364*/ uint16(x86_xCondDataSize), 3344, 3352, 3368,
+ /*3368*/ uint16(x86_xSetOp), uint16(x86_PINSRQ),
+ /*3370*/ uint16(x86_xReadSlashR),
+ /*3371*/ uint16(x86_xReadIb),
+ /*3372*/ uint16(x86_xArgXmm1),
+ /*3373*/ uint16(x86_xArgRM64),
+ /*3374*/ uint16(x86_xArgImm8u),
+ /*3375*/ uint16(x86_xMatch),
+ /*3376*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3380,
+ /*3380*/ uint16(x86_xSetOp), uint16(x86_DPPS),
+ /*3382*/ uint16(x86_xReadSlashR),
+ /*3383*/ uint16(x86_xReadIb),
+ /*3384*/ uint16(x86_xArgXmm1),
+ /*3385*/ uint16(x86_xArgXmm2M128),
+ /*3386*/ uint16(x86_xArgImm8u),
+ /*3387*/ uint16(x86_xMatch),
+ /*3388*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3392,
+ /*3392*/ uint16(x86_xSetOp), uint16(x86_DPPD),
+ /*3394*/ uint16(x86_xReadSlashR),
+ /*3395*/ uint16(x86_xReadIb),
+ /*3396*/ uint16(x86_xArgXmm1),
+ /*3397*/ uint16(x86_xArgXmm2M128),
+ /*3398*/ uint16(x86_xArgImm8u),
+ /*3399*/ uint16(x86_xMatch),
+ /*3400*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3404,
+ /*3404*/ uint16(x86_xSetOp), uint16(x86_MPSADBW),
+ /*3406*/ uint16(x86_xReadSlashR),
+ /*3407*/ uint16(x86_xReadIb),
+ /*3408*/ uint16(x86_xArgXmm1),
+ /*3409*/ uint16(x86_xArgXmm2M128),
+ /*3410*/ uint16(x86_xArgImm8u),
+ /*3411*/ uint16(x86_xMatch),
+ /*3412*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3416,
+ /*3416*/ uint16(x86_xSetOp), uint16(x86_PCLMULQDQ),
+ /*3418*/ uint16(x86_xReadSlashR),
+ /*3419*/ uint16(x86_xReadIb),
+ /*3420*/ uint16(x86_xArgXmm1),
+ /*3421*/ uint16(x86_xArgXmm2M128),
+ /*3422*/ uint16(x86_xArgImm8u),
+ /*3423*/ uint16(x86_xMatch),
+ /*3424*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3428,
+ /*3428*/ uint16(x86_xSetOp), uint16(x86_PCMPESTRM),
+ /*3430*/ uint16(x86_xReadSlashR),
+ /*3431*/ uint16(x86_xReadIb),
+ /*3432*/ uint16(x86_xArgXmm1),
+ /*3433*/ uint16(x86_xArgXmm2M128),
+ /*3434*/ uint16(x86_xArgImm8u),
+ /*3435*/ uint16(x86_xMatch),
+ /*3436*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3440,
+ /*3440*/ uint16(x86_xSetOp), uint16(x86_PCMPESTRI),
+ /*3442*/ uint16(x86_xReadSlashR),
+ /*3443*/ uint16(x86_xReadIb),
+ /*3444*/ uint16(x86_xArgXmm1),
+ /*3445*/ uint16(x86_xArgXmm2M128),
+ /*3446*/ uint16(x86_xArgImm8u),
+ /*3447*/ uint16(x86_xMatch),
+ /*3448*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3452,
+ /*3452*/ uint16(x86_xSetOp), uint16(x86_PCMPISTRM),
+ /*3454*/ uint16(x86_xReadSlashR),
+ /*3455*/ uint16(x86_xReadIb),
+ /*3456*/ uint16(x86_xArgXmm1),
+ /*3457*/ uint16(x86_xArgXmm2M128),
+ /*3458*/ uint16(x86_xArgImm8u),
+ /*3459*/ uint16(x86_xMatch),
+ /*3460*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3464,
+ /*3464*/ uint16(x86_xSetOp), uint16(x86_PCMPISTRI),
+ /*3466*/ uint16(x86_xReadSlashR),
+ /*3467*/ uint16(x86_xReadIb),
+ /*3468*/ uint16(x86_xArgXmm1),
+ /*3469*/ uint16(x86_xArgXmm2M128),
+ /*3470*/ uint16(x86_xArgImm8u),
+ /*3471*/ uint16(x86_xMatch),
+ /*3472*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 3476,
+ /*3476*/ uint16(x86_xSetOp), uint16(x86_AESKEYGENASSIST),
+ /*3478*/ uint16(x86_xReadSlashR),
+ /*3479*/ uint16(x86_xReadIb),
+ /*3480*/ uint16(x86_xArgXmm1),
+ /*3481*/ uint16(x86_xArgXmm2M128),
+ /*3482*/ uint16(x86_xArgImm8u),
+ /*3483*/ uint16(x86_xMatch),
+ /*3484*/ uint16(x86_xCondIs64), 3487, 3503,
+ /*3487*/ uint16(x86_xCondDataSize), 3491, 3497, 0,
+ /*3491*/ uint16(x86_xSetOp), uint16(x86_CMOVO),
+ /*3493*/ uint16(x86_xReadSlashR),
+ /*3494*/ uint16(x86_xArgR16),
+ /*3495*/ uint16(x86_xArgRM16),
+ /*3496*/ uint16(x86_xMatch),
+ /*3497*/ uint16(x86_xSetOp), uint16(x86_CMOVO),
+ /*3499*/ uint16(x86_xReadSlashR),
+ /*3500*/ uint16(x86_xArgR32),
+ /*3501*/ uint16(x86_xArgRM32),
+ /*3502*/ uint16(x86_xMatch),
+ /*3503*/ uint16(x86_xCondDataSize), 3491, 3497, 3507,
+ /*3507*/ uint16(x86_xSetOp), uint16(x86_CMOVO),
+ /*3509*/ uint16(x86_xReadSlashR),
+ /*3510*/ uint16(x86_xArgR64),
+ /*3511*/ uint16(x86_xArgRM64),
+ /*3512*/ uint16(x86_xMatch),
+ /*3513*/ uint16(x86_xCondIs64), 3516, 3532,
+ /*3516*/ uint16(x86_xCondDataSize), 3520, 3526, 0,
+ /*3520*/ uint16(x86_xSetOp), uint16(x86_CMOVNO),
+ /*3522*/ uint16(x86_xReadSlashR),
+ /*3523*/ uint16(x86_xArgR16),
+ /*3524*/ uint16(x86_xArgRM16),
+ /*3525*/ uint16(x86_xMatch),
+ /*3526*/ uint16(x86_xSetOp), uint16(x86_CMOVNO),
+ /*3528*/ uint16(x86_xReadSlashR),
+ /*3529*/ uint16(x86_xArgR32),
+ /*3530*/ uint16(x86_xArgRM32),
+ /*3531*/ uint16(x86_xMatch),
+ /*3532*/ uint16(x86_xCondDataSize), 3520, 3526, 3536,
+ /*3536*/ uint16(x86_xSetOp), uint16(x86_CMOVNO),
+ /*3538*/ uint16(x86_xReadSlashR),
+ /*3539*/ uint16(x86_xArgR64),
+ /*3540*/ uint16(x86_xArgRM64),
+ /*3541*/ uint16(x86_xMatch),
+ /*3542*/ uint16(x86_xCondIs64), 3545, 3561,
+ /*3545*/ uint16(x86_xCondDataSize), 3549, 3555, 0,
+ /*3549*/ uint16(x86_xSetOp), uint16(x86_CMOVB),
+ /*3551*/ uint16(x86_xReadSlashR),
+ /*3552*/ uint16(x86_xArgR16),
+ /*3553*/ uint16(x86_xArgRM16),
+ /*3554*/ uint16(x86_xMatch),
+ /*3555*/ uint16(x86_xSetOp), uint16(x86_CMOVB),
+ /*3557*/ uint16(x86_xReadSlashR),
+ /*3558*/ uint16(x86_xArgR32),
+ /*3559*/ uint16(x86_xArgRM32),
+ /*3560*/ uint16(x86_xMatch),
+ /*3561*/ uint16(x86_xCondDataSize), 3549, 3555, 3565,
+ /*3565*/ uint16(x86_xSetOp), uint16(x86_CMOVB),
+ /*3567*/ uint16(x86_xReadSlashR),
+ /*3568*/ uint16(x86_xArgR64),
+ /*3569*/ uint16(x86_xArgRM64),
+ /*3570*/ uint16(x86_xMatch),
+ /*3571*/ uint16(x86_xCondIs64), 3574, 3590,
+ /*3574*/ uint16(x86_xCondDataSize), 3578, 3584, 0,
+ /*3578*/ uint16(x86_xSetOp), uint16(x86_CMOVAE),
+ /*3580*/ uint16(x86_xReadSlashR),
+ /*3581*/ uint16(x86_xArgR16),
+ /*3582*/ uint16(x86_xArgRM16),
+ /*3583*/ uint16(x86_xMatch),
+ /*3584*/ uint16(x86_xSetOp), uint16(x86_CMOVAE),
+ /*3586*/ uint16(x86_xReadSlashR),
+ /*3587*/ uint16(x86_xArgR32),
+ /*3588*/ uint16(x86_xArgRM32),
+ /*3589*/ uint16(x86_xMatch),
+ /*3590*/ uint16(x86_xCondDataSize), 3578, 3584, 3594,
+ /*3594*/ uint16(x86_xSetOp), uint16(x86_CMOVAE),
+ /*3596*/ uint16(x86_xReadSlashR),
+ /*3597*/ uint16(x86_xArgR64),
+ /*3598*/ uint16(x86_xArgRM64),
+ /*3599*/ uint16(x86_xMatch),
+ /*3600*/ uint16(x86_xCondIs64), 3603, 3619,
+ /*3603*/ uint16(x86_xCondDataSize), 3607, 3613, 0,
+ /*3607*/ uint16(x86_xSetOp), uint16(x86_CMOVE),
+ /*3609*/ uint16(x86_xReadSlashR),
+ /*3610*/ uint16(x86_xArgR16),
+ /*3611*/ uint16(x86_xArgRM16),
+ /*3612*/ uint16(x86_xMatch),
+ /*3613*/ uint16(x86_xSetOp), uint16(x86_CMOVE),
+ /*3615*/ uint16(x86_xReadSlashR),
+ /*3616*/ uint16(x86_xArgR32),
+ /*3617*/ uint16(x86_xArgRM32),
+ /*3618*/ uint16(x86_xMatch),
+ /*3619*/ uint16(x86_xCondDataSize), 3607, 3613, 3623,
+ /*3623*/ uint16(x86_xSetOp), uint16(x86_CMOVE),
+ /*3625*/ uint16(x86_xReadSlashR),
+ /*3626*/ uint16(x86_xArgR64),
+ /*3627*/ uint16(x86_xArgRM64),
+ /*3628*/ uint16(x86_xMatch),
+ /*3629*/ uint16(x86_xCondIs64), 3632, 3648,
+ /*3632*/ uint16(x86_xCondDataSize), 3636, 3642, 0,
+ /*3636*/ uint16(x86_xSetOp), uint16(x86_CMOVNE),
+ /*3638*/ uint16(x86_xReadSlashR),
+ /*3639*/ uint16(x86_xArgR16),
+ /*3640*/ uint16(x86_xArgRM16),
+ /*3641*/ uint16(x86_xMatch),
+ /*3642*/ uint16(x86_xSetOp), uint16(x86_CMOVNE),
+ /*3644*/ uint16(x86_xReadSlashR),
+ /*3645*/ uint16(x86_xArgR32),
+ /*3646*/ uint16(x86_xArgRM32),
+ /*3647*/ uint16(x86_xMatch),
+ /*3648*/ uint16(x86_xCondDataSize), 3636, 3642, 3652,
+ /*3652*/ uint16(x86_xSetOp), uint16(x86_CMOVNE),
+ /*3654*/ uint16(x86_xReadSlashR),
+ /*3655*/ uint16(x86_xArgR64),
+ /*3656*/ uint16(x86_xArgRM64),
+ /*3657*/ uint16(x86_xMatch),
+ /*3658*/ uint16(x86_xCondIs64), 3661, 3677,
+ /*3661*/ uint16(x86_xCondDataSize), 3665, 3671, 0,
+ /*3665*/ uint16(x86_xSetOp), uint16(x86_CMOVBE),
+ /*3667*/ uint16(x86_xReadSlashR),
+ /*3668*/ uint16(x86_xArgR16),
+ /*3669*/ uint16(x86_xArgRM16),
+ /*3670*/ uint16(x86_xMatch),
+ /*3671*/ uint16(x86_xSetOp), uint16(x86_CMOVBE),
+ /*3673*/ uint16(x86_xReadSlashR),
+ /*3674*/ uint16(x86_xArgR32),
+ /*3675*/ uint16(x86_xArgRM32),
+ /*3676*/ uint16(x86_xMatch),
+ /*3677*/ uint16(x86_xCondDataSize), 3665, 3671, 3681,
+ /*3681*/ uint16(x86_xSetOp), uint16(x86_CMOVBE),
+ /*3683*/ uint16(x86_xReadSlashR),
+ /*3684*/ uint16(x86_xArgR64),
+ /*3685*/ uint16(x86_xArgRM64),
+ /*3686*/ uint16(x86_xMatch),
+ /*3687*/ uint16(x86_xCondIs64), 3690, 3706,
+ /*3690*/ uint16(x86_xCondDataSize), 3694, 3700, 0,
+ /*3694*/ uint16(x86_xSetOp), uint16(x86_CMOVA),
+ /*3696*/ uint16(x86_xReadSlashR),
+ /*3697*/ uint16(x86_xArgR16),
+ /*3698*/ uint16(x86_xArgRM16),
+ /*3699*/ uint16(x86_xMatch),
+ /*3700*/ uint16(x86_xSetOp), uint16(x86_CMOVA),
+ /*3702*/ uint16(x86_xReadSlashR),
+ /*3703*/ uint16(x86_xArgR32),
+ /*3704*/ uint16(x86_xArgRM32),
+ /*3705*/ uint16(x86_xMatch),
+ /*3706*/ uint16(x86_xCondDataSize), 3694, 3700, 3710,
+ /*3710*/ uint16(x86_xSetOp), uint16(x86_CMOVA),
+ /*3712*/ uint16(x86_xReadSlashR),
+ /*3713*/ uint16(x86_xArgR64),
+ /*3714*/ uint16(x86_xArgRM64),
+ /*3715*/ uint16(x86_xMatch),
+ /*3716*/ uint16(x86_xCondIs64), 3719, 3735,
+ /*3719*/ uint16(x86_xCondDataSize), 3723, 3729, 0,
+ /*3723*/ uint16(x86_xSetOp), uint16(x86_CMOVS),
+ /*3725*/ uint16(x86_xReadSlashR),
+ /*3726*/ uint16(x86_xArgR16),
+ /*3727*/ uint16(x86_xArgRM16),
+ /*3728*/ uint16(x86_xMatch),
+ /*3729*/ uint16(x86_xSetOp), uint16(x86_CMOVS),
+ /*3731*/ uint16(x86_xReadSlashR),
+ /*3732*/ uint16(x86_xArgR32),
+ /*3733*/ uint16(x86_xArgRM32),
+ /*3734*/ uint16(x86_xMatch),
+ /*3735*/ uint16(x86_xCondDataSize), 3723, 3729, 3739,
+ /*3739*/ uint16(x86_xSetOp), uint16(x86_CMOVS),
+ /*3741*/ uint16(x86_xReadSlashR),
+ /*3742*/ uint16(x86_xArgR64),
+ /*3743*/ uint16(x86_xArgRM64),
+ /*3744*/ uint16(x86_xMatch),
+ /*3745*/ uint16(x86_xCondIs64), 3748, 3764,
+ /*3748*/ uint16(x86_xCondDataSize), 3752, 3758, 0,
+ /*3752*/ uint16(x86_xSetOp), uint16(x86_CMOVNS),
+ /*3754*/ uint16(x86_xReadSlashR),
+ /*3755*/ uint16(x86_xArgR16),
+ /*3756*/ uint16(x86_xArgRM16),
+ /*3757*/ uint16(x86_xMatch),
+ /*3758*/ uint16(x86_xSetOp), uint16(x86_CMOVNS),
+ /*3760*/ uint16(x86_xReadSlashR),
+ /*3761*/ uint16(x86_xArgR32),
+ /*3762*/ uint16(x86_xArgRM32),
+ /*3763*/ uint16(x86_xMatch),
+ /*3764*/ uint16(x86_xCondDataSize), 3752, 3758, 3768,
+ /*3768*/ uint16(x86_xSetOp), uint16(x86_CMOVNS),
+ /*3770*/ uint16(x86_xReadSlashR),
+ /*3771*/ uint16(x86_xArgR64),
+ /*3772*/ uint16(x86_xArgRM64),
+ /*3773*/ uint16(x86_xMatch),
+ /*3774*/ uint16(x86_xCondIs64), 3777, 3793,
+ /*3777*/ uint16(x86_xCondDataSize), 3781, 3787, 0,
+ /*3781*/ uint16(x86_xSetOp), uint16(x86_CMOVP),
+ /*3783*/ uint16(x86_xReadSlashR),
+ /*3784*/ uint16(x86_xArgR16),
+ /*3785*/ uint16(x86_xArgRM16),
+ /*3786*/ uint16(x86_xMatch),
+ /*3787*/ uint16(x86_xSetOp), uint16(x86_CMOVP),
+ /*3789*/ uint16(x86_xReadSlashR),
+ /*3790*/ uint16(x86_xArgR32),
+ /*3791*/ uint16(x86_xArgRM32),
+ /*3792*/ uint16(x86_xMatch),
+ /*3793*/ uint16(x86_xCondDataSize), 3781, 3787, 3797,
+ /*3797*/ uint16(x86_xSetOp), uint16(x86_CMOVP),
+ /*3799*/ uint16(x86_xReadSlashR),
+ /*3800*/ uint16(x86_xArgR64),
+ /*3801*/ uint16(x86_xArgRM64),
+ /*3802*/ uint16(x86_xMatch),
+ /*3803*/ uint16(x86_xCondIs64), 3806, 3822,
+ /*3806*/ uint16(x86_xCondDataSize), 3810, 3816, 0,
+ /*3810*/ uint16(x86_xSetOp), uint16(x86_CMOVNP),
+ /*3812*/ uint16(x86_xReadSlashR),
+ /*3813*/ uint16(x86_xArgR16),
+ /*3814*/ uint16(x86_xArgRM16),
+ /*3815*/ uint16(x86_xMatch),
+ /*3816*/ uint16(x86_xSetOp), uint16(x86_CMOVNP),
+ /*3818*/ uint16(x86_xReadSlashR),
+ /*3819*/ uint16(x86_xArgR32),
+ /*3820*/ uint16(x86_xArgRM32),
+ /*3821*/ uint16(x86_xMatch),
+ /*3822*/ uint16(x86_xCondDataSize), 3810, 3816, 3826,
+ /*3826*/ uint16(x86_xSetOp), uint16(x86_CMOVNP),
+ /*3828*/ uint16(x86_xReadSlashR),
+ /*3829*/ uint16(x86_xArgR64),
+ /*3830*/ uint16(x86_xArgRM64),
+ /*3831*/ uint16(x86_xMatch),
+ /*3832*/ uint16(x86_xCondIs64), 3835, 3851,
+ /*3835*/ uint16(x86_xCondDataSize), 3839, 3845, 0,
+ /*3839*/ uint16(x86_xSetOp), uint16(x86_CMOVL),
+ /*3841*/ uint16(x86_xReadSlashR),
+ /*3842*/ uint16(x86_xArgR16),
+ /*3843*/ uint16(x86_xArgRM16),
+ /*3844*/ uint16(x86_xMatch),
+ /*3845*/ uint16(x86_xSetOp), uint16(x86_CMOVL),
+ /*3847*/ uint16(x86_xReadSlashR),
+ /*3848*/ uint16(x86_xArgR32),
+ /*3849*/ uint16(x86_xArgRM32),
+ /*3850*/ uint16(x86_xMatch),
+ /*3851*/ uint16(x86_xCondDataSize), 3839, 3845, 3855,
+ /*3855*/ uint16(x86_xSetOp), uint16(x86_CMOVL),
+ /*3857*/ uint16(x86_xReadSlashR),
+ /*3858*/ uint16(x86_xArgR64),
+ /*3859*/ uint16(x86_xArgRM64),
+ /*3860*/ uint16(x86_xMatch),
+ /*3861*/ uint16(x86_xCondIs64), 3864, 3880,
+ /*3864*/ uint16(x86_xCondDataSize), 3868, 3874, 0,
+ /*3868*/ uint16(x86_xSetOp), uint16(x86_CMOVGE),
+ /*3870*/ uint16(x86_xReadSlashR),
+ /*3871*/ uint16(x86_xArgR16),
+ /*3872*/ uint16(x86_xArgRM16),
+ /*3873*/ uint16(x86_xMatch),
+ /*3874*/ uint16(x86_xSetOp), uint16(x86_CMOVGE),
+ /*3876*/ uint16(x86_xReadSlashR),
+ /*3877*/ uint16(x86_xArgR32),
+ /*3878*/ uint16(x86_xArgRM32),
+ /*3879*/ uint16(x86_xMatch),
+ /*3880*/ uint16(x86_xCondDataSize), 3868, 3874, 3884,
+ /*3884*/ uint16(x86_xSetOp), uint16(x86_CMOVGE),
+ /*3886*/ uint16(x86_xReadSlashR),
+ /*3887*/ uint16(x86_xArgR64),
+ /*3888*/ uint16(x86_xArgRM64),
+ /*3889*/ uint16(x86_xMatch),
+ /*3890*/ uint16(x86_xCondIs64), 3893, 3909,
+ /*3893*/ uint16(x86_xCondDataSize), 3897, 3903, 0,
+ /*3897*/ uint16(x86_xSetOp), uint16(x86_CMOVLE),
+ /*3899*/ uint16(x86_xReadSlashR),
+ /*3900*/ uint16(x86_xArgR16),
+ /*3901*/ uint16(x86_xArgRM16),
+ /*3902*/ uint16(x86_xMatch),
+ /*3903*/ uint16(x86_xSetOp), uint16(x86_CMOVLE),
+ /*3905*/ uint16(x86_xReadSlashR),
+ /*3906*/ uint16(x86_xArgR32),
+ /*3907*/ uint16(x86_xArgRM32),
+ /*3908*/ uint16(x86_xMatch),
+ /*3909*/ uint16(x86_xCondDataSize), 3897, 3903, 3913,
+ /*3913*/ uint16(x86_xSetOp), uint16(x86_CMOVLE),
+ /*3915*/ uint16(x86_xReadSlashR),
+ /*3916*/ uint16(x86_xArgR64),
+ /*3917*/ uint16(x86_xArgRM64),
+ /*3918*/ uint16(x86_xMatch),
+ /*3919*/ uint16(x86_xCondIs64), 3922, 3938,
+ /*3922*/ uint16(x86_xCondDataSize), 3926, 3932, 0,
+ /*3926*/ uint16(x86_xSetOp), uint16(x86_CMOVG),
+ /*3928*/ uint16(x86_xReadSlashR),
+ /*3929*/ uint16(x86_xArgR16),
+ /*3930*/ uint16(x86_xArgRM16),
+ /*3931*/ uint16(x86_xMatch),
+ /*3932*/ uint16(x86_xSetOp), uint16(x86_CMOVG),
+ /*3934*/ uint16(x86_xReadSlashR),
+ /*3935*/ uint16(x86_xArgR32),
+ /*3936*/ uint16(x86_xArgRM32),
+ /*3937*/ uint16(x86_xMatch),
+ /*3938*/ uint16(x86_xCondDataSize), 3926, 3932, 3942,
+ /*3942*/ uint16(x86_xSetOp), uint16(x86_CMOVG),
+ /*3944*/ uint16(x86_xReadSlashR),
+ /*3945*/ uint16(x86_xArgR64),
+ /*3946*/ uint16(x86_xArgRM64),
+ /*3947*/ uint16(x86_xMatch),
+ /*3948*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 3960,
+ 0x0, 3954,
+ /*3954*/ uint16(x86_xSetOp), uint16(x86_MOVMSKPS),
+ /*3956*/ uint16(x86_xReadSlashR),
+ /*3957*/ uint16(x86_xArgR32),
+ /*3958*/ uint16(x86_xArgXmm2),
+ /*3959*/ uint16(x86_xMatch),
+ /*3960*/ uint16(x86_xSetOp), uint16(x86_MOVMSKPD),
+ /*3962*/ uint16(x86_xReadSlashR),
+ /*3963*/ uint16(x86_xArgR32),
+ /*3964*/ uint16(x86_xArgXmm2),
+ /*3965*/ uint16(x86_xMatch),
+ /*3966*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 3994,
+ 0xF2, 3988,
+ 0x66, 3982,
+ 0x0, 3976,
+ /*3976*/ uint16(x86_xSetOp), uint16(x86_SQRTPS),
+ /*3978*/ uint16(x86_xReadSlashR),
+ /*3979*/ uint16(x86_xArgXmm1),
+ /*3980*/ uint16(x86_xArgXmm2M128),
+ /*3981*/ uint16(x86_xMatch),
+ /*3982*/ uint16(x86_xSetOp), uint16(x86_SQRTPD),
+ /*3984*/ uint16(x86_xReadSlashR),
+ /*3985*/ uint16(x86_xArgXmm1),
+ /*3986*/ uint16(x86_xArgXmm2M128),
+ /*3987*/ uint16(x86_xMatch),
+ /*3988*/ uint16(x86_xSetOp), uint16(x86_SQRTSD),
+ /*3990*/ uint16(x86_xReadSlashR),
+ /*3991*/ uint16(x86_xArgXmm1),
+ /*3992*/ uint16(x86_xArgXmm2M64),
+ /*3993*/ uint16(x86_xMatch),
+ /*3994*/ uint16(x86_xSetOp), uint16(x86_SQRTSS),
+ /*3996*/ uint16(x86_xReadSlashR),
+ /*3997*/ uint16(x86_xArgXmm1),
+ /*3998*/ uint16(x86_xArgXmm2M32),
+ /*3999*/ uint16(x86_xMatch),
+ /*4000*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 4012,
+ 0x0, 4006,
+ /*4006*/ uint16(x86_xSetOp), uint16(x86_RSQRTPS),
+ /*4008*/ uint16(x86_xReadSlashR),
+ /*4009*/ uint16(x86_xArgXmm1),
+ /*4010*/ uint16(x86_xArgXmm2M128),
+ /*4011*/ uint16(x86_xMatch),
+ /*4012*/ uint16(x86_xSetOp), uint16(x86_RSQRTSS),
+ /*4014*/ uint16(x86_xReadSlashR),
+ /*4015*/ uint16(x86_xArgXmm1),
+ /*4016*/ uint16(x86_xArgXmm2M32),
+ /*4017*/ uint16(x86_xMatch),
+ /*4018*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 4030,
+ 0x0, 4024,
+ /*4024*/ uint16(x86_xSetOp), uint16(x86_RCPPS),
+ /*4026*/ uint16(x86_xReadSlashR),
+ /*4027*/ uint16(x86_xArgXmm1),
+ /*4028*/ uint16(x86_xArgXmm2M128),
+ /*4029*/ uint16(x86_xMatch),
+ /*4030*/ uint16(x86_xSetOp), uint16(x86_RCPSS),
+ /*4032*/ uint16(x86_xReadSlashR),
+ /*4033*/ uint16(x86_xArgXmm1),
+ /*4034*/ uint16(x86_xArgXmm2M32),
+ /*4035*/ uint16(x86_xMatch),
+ /*4036*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4048,
+ 0x0, 4042,
+ /*4042*/ uint16(x86_xSetOp), uint16(x86_ANDPS),
+ /*4044*/ uint16(x86_xReadSlashR),
+ /*4045*/ uint16(x86_xArgXmm1),
+ /*4046*/ uint16(x86_xArgXmm2M128),
+ /*4047*/ uint16(x86_xMatch),
+ /*4048*/ uint16(x86_xSetOp), uint16(x86_ANDPD),
+ /*4050*/ uint16(x86_xReadSlashR),
+ /*4051*/ uint16(x86_xArgXmm1),
+ /*4052*/ uint16(x86_xArgXmm2M128),
+ /*4053*/ uint16(x86_xMatch),
+ /*4054*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4066,
+ 0x0, 4060,
+ /*4060*/ uint16(x86_xSetOp), uint16(x86_ANDNPS),
+ /*4062*/ uint16(x86_xReadSlashR),
+ /*4063*/ uint16(x86_xArgXmm1),
+ /*4064*/ uint16(x86_xArgXmm2M128),
+ /*4065*/ uint16(x86_xMatch),
+ /*4066*/ uint16(x86_xSetOp), uint16(x86_ANDNPD),
+ /*4068*/ uint16(x86_xReadSlashR),
+ /*4069*/ uint16(x86_xArgXmm1),
+ /*4070*/ uint16(x86_xArgXmm2M128),
+ /*4071*/ uint16(x86_xMatch),
+ /*4072*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4084,
+ 0x0, 4078,
+ /*4078*/ uint16(x86_xSetOp), uint16(x86_ORPS),
+ /*4080*/ uint16(x86_xReadSlashR),
+ /*4081*/ uint16(x86_xArgXmm1),
+ /*4082*/ uint16(x86_xArgXmm2M128),
+ /*4083*/ uint16(x86_xMatch),
+ /*4084*/ uint16(x86_xSetOp), uint16(x86_ORPD),
+ /*4086*/ uint16(x86_xReadSlashR),
+ /*4087*/ uint16(x86_xArgXmm1),
+ /*4088*/ uint16(x86_xArgXmm2M128),
+ /*4089*/ uint16(x86_xMatch),
+ /*4090*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4102,
+ 0x0, 4096,
+ /*4096*/ uint16(x86_xSetOp), uint16(x86_XORPS),
+ /*4098*/ uint16(x86_xReadSlashR),
+ /*4099*/ uint16(x86_xArgXmm1),
+ /*4100*/ uint16(x86_xArgXmm2M128),
+ /*4101*/ uint16(x86_xMatch),
+ /*4102*/ uint16(x86_xSetOp), uint16(x86_XORPD),
+ /*4104*/ uint16(x86_xReadSlashR),
+ /*4105*/ uint16(x86_xArgXmm1),
+ /*4106*/ uint16(x86_xArgXmm2M128),
+ /*4107*/ uint16(x86_xMatch),
+ /*4108*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4136,
+ 0xF2, 4130,
+ 0x66, 4124,
+ 0x0, 4118,
+ /*4118*/ uint16(x86_xSetOp), uint16(x86_ADDPS),
+ /*4120*/ uint16(x86_xReadSlashR),
+ /*4121*/ uint16(x86_xArgXmm1),
+ /*4122*/ uint16(x86_xArgXmm2M128),
+ /*4123*/ uint16(x86_xMatch),
+ /*4124*/ uint16(x86_xSetOp), uint16(x86_ADDPD),
+ /*4126*/ uint16(x86_xReadSlashR),
+ /*4127*/ uint16(x86_xArgXmm1),
+ /*4128*/ uint16(x86_xArgXmm2M128),
+ /*4129*/ uint16(x86_xMatch),
+ /*4130*/ uint16(x86_xSetOp), uint16(x86_ADDSD),
+ /*4132*/ uint16(x86_xReadSlashR),
+ /*4133*/ uint16(x86_xArgXmm1),
+ /*4134*/ uint16(x86_xArgXmm2M64),
+ /*4135*/ uint16(x86_xMatch),
+ /*4136*/ uint16(x86_xSetOp), uint16(x86_ADDSS),
+ /*4138*/ uint16(x86_xReadSlashR),
+ /*4139*/ uint16(x86_xArgXmm1),
+ /*4140*/ uint16(x86_xArgXmm2M32),
+ /*4141*/ uint16(x86_xMatch),
+ /*4142*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4170,
+ 0xF2, 4164,
+ 0x66, 4158,
+ 0x0, 4152,
+ /*4152*/ uint16(x86_xSetOp), uint16(x86_MULPS),
+ /*4154*/ uint16(x86_xReadSlashR),
+ /*4155*/ uint16(x86_xArgXmm1),
+ /*4156*/ uint16(x86_xArgXmm2M128),
+ /*4157*/ uint16(x86_xMatch),
+ /*4158*/ uint16(x86_xSetOp), uint16(x86_MULPD),
+ /*4160*/ uint16(x86_xReadSlashR),
+ /*4161*/ uint16(x86_xArgXmm1),
+ /*4162*/ uint16(x86_xArgXmm2M128),
+ /*4163*/ uint16(x86_xMatch),
+ /*4164*/ uint16(x86_xSetOp), uint16(x86_MULSD),
+ /*4166*/ uint16(x86_xReadSlashR),
+ /*4167*/ uint16(x86_xArgXmm1),
+ /*4168*/ uint16(x86_xArgXmm2M64),
+ /*4169*/ uint16(x86_xMatch),
+ /*4170*/ uint16(x86_xSetOp), uint16(x86_MULSS),
+ /*4172*/ uint16(x86_xReadSlashR),
+ /*4173*/ uint16(x86_xArgXmm1),
+ /*4174*/ uint16(x86_xArgXmm2M32),
+ /*4175*/ uint16(x86_xMatch),
+ /*4176*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4204,
+ 0xF2, 4198,
+ 0x66, 4192,
+ 0x0, 4186,
+ /*4186*/ uint16(x86_xSetOp), uint16(x86_CVTPS2PD),
+ /*4188*/ uint16(x86_xReadSlashR),
+ /*4189*/ uint16(x86_xArgXmm1),
+ /*4190*/ uint16(x86_xArgXmm2M64),
+ /*4191*/ uint16(x86_xMatch),
+ /*4192*/ uint16(x86_xSetOp), uint16(x86_CVTPD2PS),
+ /*4194*/ uint16(x86_xReadSlashR),
+ /*4195*/ uint16(x86_xArgXmm1),
+ /*4196*/ uint16(x86_xArgXmm2M128),
+ /*4197*/ uint16(x86_xMatch),
+ /*4198*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SS),
+ /*4200*/ uint16(x86_xReadSlashR),
+ /*4201*/ uint16(x86_xArgXmm1),
+ /*4202*/ uint16(x86_xArgXmm2M64),
+ /*4203*/ uint16(x86_xMatch),
+ /*4204*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SD),
+ /*4206*/ uint16(x86_xReadSlashR),
+ /*4207*/ uint16(x86_xArgXmm1),
+ /*4208*/ uint16(x86_xArgXmm2M32),
+ /*4209*/ uint16(x86_xMatch),
+ /*4210*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 4230,
+ 0x66, 4224,
+ 0x0, 4218,
+ /*4218*/ uint16(x86_xSetOp), uint16(x86_CVTDQ2PS),
+ /*4220*/ uint16(x86_xReadSlashR),
+ /*4221*/ uint16(x86_xArgXmm1),
+ /*4222*/ uint16(x86_xArgXmm2M128),
+ /*4223*/ uint16(x86_xMatch),
+ /*4224*/ uint16(x86_xSetOp), uint16(x86_CVTPS2DQ),
+ /*4226*/ uint16(x86_xReadSlashR),
+ /*4227*/ uint16(x86_xArgXmm1),
+ /*4228*/ uint16(x86_xArgXmm2M128),
+ /*4229*/ uint16(x86_xMatch),
+ /*4230*/ uint16(x86_xSetOp), uint16(x86_CVTTPS2DQ),
+ /*4232*/ uint16(x86_xReadSlashR),
+ /*4233*/ uint16(x86_xArgXmm1),
+ /*4234*/ uint16(x86_xArgXmm2M128),
+ /*4235*/ uint16(x86_xMatch),
+ /*4236*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4264,
+ 0xF2, 4258,
+ 0x66, 4252,
+ 0x0, 4246,
+ /*4246*/ uint16(x86_xSetOp), uint16(x86_SUBPS),
+ /*4248*/ uint16(x86_xReadSlashR),
+ /*4249*/ uint16(x86_xArgXmm1),
+ /*4250*/ uint16(x86_xArgXmm2M128),
+ /*4251*/ uint16(x86_xMatch),
+ /*4252*/ uint16(x86_xSetOp), uint16(x86_SUBPD),
+ /*4254*/ uint16(x86_xReadSlashR),
+ /*4255*/ uint16(x86_xArgXmm1),
+ /*4256*/ uint16(x86_xArgXmm2M128),
+ /*4257*/ uint16(x86_xMatch),
+ /*4258*/ uint16(x86_xSetOp), uint16(x86_SUBSD),
+ /*4260*/ uint16(x86_xReadSlashR),
+ /*4261*/ uint16(x86_xArgXmm1),
+ /*4262*/ uint16(x86_xArgXmm2M64),
+ /*4263*/ uint16(x86_xMatch),
+ /*4264*/ uint16(x86_xSetOp), uint16(x86_SUBSS),
+ /*4266*/ uint16(x86_xReadSlashR),
+ /*4267*/ uint16(x86_xArgXmm1),
+ /*4268*/ uint16(x86_xArgXmm2M32),
+ /*4269*/ uint16(x86_xMatch),
+ /*4270*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4298,
+ 0xF2, 4292,
+ 0x66, 4286,
+ 0x0, 4280,
+ /*4280*/ uint16(x86_xSetOp), uint16(x86_MINPS),
+ /*4282*/ uint16(x86_xReadSlashR),
+ /*4283*/ uint16(x86_xArgXmm1),
+ /*4284*/ uint16(x86_xArgXmm2M128),
+ /*4285*/ uint16(x86_xMatch),
+ /*4286*/ uint16(x86_xSetOp), uint16(x86_MINPD),
+ /*4288*/ uint16(x86_xReadSlashR),
+ /*4289*/ uint16(x86_xArgXmm1),
+ /*4290*/ uint16(x86_xArgXmm2M128),
+ /*4291*/ uint16(x86_xMatch),
+ /*4292*/ uint16(x86_xSetOp), uint16(x86_MINSD),
+ /*4294*/ uint16(x86_xReadSlashR),
+ /*4295*/ uint16(x86_xArgXmm1),
+ /*4296*/ uint16(x86_xArgXmm2M64),
+ /*4297*/ uint16(x86_xMatch),
+ /*4298*/ uint16(x86_xSetOp), uint16(x86_MINSS),
+ /*4300*/ uint16(x86_xReadSlashR),
+ /*4301*/ uint16(x86_xArgXmm1),
+ /*4302*/ uint16(x86_xArgXmm2M32),
+ /*4303*/ uint16(x86_xMatch),
+ /*4304*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4332,
+ 0xF2, 4326,
+ 0x66, 4320,
+ 0x0, 4314,
+ /*4314*/ uint16(x86_xSetOp), uint16(x86_DIVPS),
+ /*4316*/ uint16(x86_xReadSlashR),
+ /*4317*/ uint16(x86_xArgXmm1),
+ /*4318*/ uint16(x86_xArgXmm2M128),
+ /*4319*/ uint16(x86_xMatch),
+ /*4320*/ uint16(x86_xSetOp), uint16(x86_DIVPD),
+ /*4322*/ uint16(x86_xReadSlashR),
+ /*4323*/ uint16(x86_xArgXmm1),
+ /*4324*/ uint16(x86_xArgXmm2M128),
+ /*4325*/ uint16(x86_xMatch),
+ /*4326*/ uint16(x86_xSetOp), uint16(x86_DIVSD),
+ /*4328*/ uint16(x86_xReadSlashR),
+ /*4329*/ uint16(x86_xArgXmm1),
+ /*4330*/ uint16(x86_xArgXmm2M64),
+ /*4331*/ uint16(x86_xMatch),
+ /*4332*/ uint16(x86_xSetOp), uint16(x86_DIVSS),
+ /*4334*/ uint16(x86_xReadSlashR),
+ /*4335*/ uint16(x86_xArgXmm1),
+ /*4336*/ uint16(x86_xArgXmm2M32),
+ /*4337*/ uint16(x86_xMatch),
+ /*4338*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4366,
+ 0xF2, 4360,
+ 0x66, 4354,
+ 0x0, 4348,
+ /*4348*/ uint16(x86_xSetOp), uint16(x86_MAXPS),
+ /*4350*/ uint16(x86_xReadSlashR),
+ /*4351*/ uint16(x86_xArgXmm1),
+ /*4352*/ uint16(x86_xArgXmm2M128),
+ /*4353*/ uint16(x86_xMatch),
+ /*4354*/ uint16(x86_xSetOp), uint16(x86_MAXPD),
+ /*4356*/ uint16(x86_xReadSlashR),
+ /*4357*/ uint16(x86_xArgXmm1),
+ /*4358*/ uint16(x86_xArgXmm2M128),
+ /*4359*/ uint16(x86_xMatch),
+ /*4360*/ uint16(x86_xSetOp), uint16(x86_MAXSD),
+ /*4362*/ uint16(x86_xReadSlashR),
+ /*4363*/ uint16(x86_xArgXmm1),
+ /*4364*/ uint16(x86_xArgXmm2M64),
+ /*4365*/ uint16(x86_xMatch),
+ /*4366*/ uint16(x86_xSetOp), uint16(x86_MAXSS),
+ /*4368*/ uint16(x86_xReadSlashR),
+ /*4369*/ uint16(x86_xArgXmm1),
+ /*4370*/ uint16(x86_xArgXmm2M32),
+ /*4371*/ uint16(x86_xMatch),
+ /*4372*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4384,
+ 0x0, 4378,
+ /*4378*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLBW),
+ /*4380*/ uint16(x86_xReadSlashR),
+ /*4381*/ uint16(x86_xArgMm),
+ /*4382*/ uint16(x86_xArgMmM32),
+ /*4383*/ uint16(x86_xMatch),
+ /*4384*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLBW),
+ /*4386*/ uint16(x86_xReadSlashR),
+ /*4387*/ uint16(x86_xArgXmm1),
+ /*4388*/ uint16(x86_xArgXmm2M128),
+ /*4389*/ uint16(x86_xMatch),
+ /*4390*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4402,
+ 0x0, 4396,
+ /*4396*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLWD),
+ /*4398*/ uint16(x86_xReadSlashR),
+ /*4399*/ uint16(x86_xArgMm),
+ /*4400*/ uint16(x86_xArgMmM32),
+ /*4401*/ uint16(x86_xMatch),
+ /*4402*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLWD),
+ /*4404*/ uint16(x86_xReadSlashR),
+ /*4405*/ uint16(x86_xArgXmm1),
+ /*4406*/ uint16(x86_xArgXmm2M128),
+ /*4407*/ uint16(x86_xMatch),
+ /*4408*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4420,
+ 0x0, 4414,
+ /*4414*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLDQ),
+ /*4416*/ uint16(x86_xReadSlashR),
+ /*4417*/ uint16(x86_xArgMm),
+ /*4418*/ uint16(x86_xArgMmM32),
+ /*4419*/ uint16(x86_xMatch),
+ /*4420*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLDQ),
+ /*4422*/ uint16(x86_xReadSlashR),
+ /*4423*/ uint16(x86_xArgXmm1),
+ /*4424*/ uint16(x86_xArgXmm2M128),
+ /*4425*/ uint16(x86_xMatch),
+ /*4426*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4438,
+ 0x0, 4432,
+ /*4432*/ uint16(x86_xSetOp), uint16(x86_PACKSSWB),
+ /*4434*/ uint16(x86_xReadSlashR),
+ /*4435*/ uint16(x86_xArgMm1),
+ /*4436*/ uint16(x86_xArgMm2M64),
+ /*4437*/ uint16(x86_xMatch),
+ /*4438*/ uint16(x86_xSetOp), uint16(x86_PACKSSWB),
+ /*4440*/ uint16(x86_xReadSlashR),
+ /*4441*/ uint16(x86_xArgXmm1),
+ /*4442*/ uint16(x86_xArgXmm2M128),
+ /*4443*/ uint16(x86_xMatch),
+ /*4444*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4456,
+ 0x0, 4450,
+ /*4450*/ uint16(x86_xSetOp), uint16(x86_PCMPGTB),
+ /*4452*/ uint16(x86_xReadSlashR),
+ /*4453*/ uint16(x86_xArgMm),
+ /*4454*/ uint16(x86_xArgMmM64),
+ /*4455*/ uint16(x86_xMatch),
+ /*4456*/ uint16(x86_xSetOp), uint16(x86_PCMPGTB),
+ /*4458*/ uint16(x86_xReadSlashR),
+ /*4459*/ uint16(x86_xArgXmm1),
+ /*4460*/ uint16(x86_xArgXmm2M128),
+ /*4461*/ uint16(x86_xMatch),
+ /*4462*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4474,
+ 0x0, 4468,
+ /*4468*/ uint16(x86_xSetOp), uint16(x86_PCMPGTW),
+ /*4470*/ uint16(x86_xReadSlashR),
+ /*4471*/ uint16(x86_xArgMm),
+ /*4472*/ uint16(x86_xArgMmM64),
+ /*4473*/ uint16(x86_xMatch),
+ /*4474*/ uint16(x86_xSetOp), uint16(x86_PCMPGTW),
+ /*4476*/ uint16(x86_xReadSlashR),
+ /*4477*/ uint16(x86_xArgXmm1),
+ /*4478*/ uint16(x86_xArgXmm2M128),
+ /*4479*/ uint16(x86_xMatch),
+ /*4480*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4492,
+ 0x0, 4486,
+ /*4486*/ uint16(x86_xSetOp), uint16(x86_PCMPGTD),
+ /*4488*/ uint16(x86_xReadSlashR),
+ /*4489*/ uint16(x86_xArgMm),
+ /*4490*/ uint16(x86_xArgMmM64),
+ /*4491*/ uint16(x86_xMatch),
+ /*4492*/ uint16(x86_xSetOp), uint16(x86_PCMPGTD),
+ /*4494*/ uint16(x86_xReadSlashR),
+ /*4495*/ uint16(x86_xArgXmm1),
+ /*4496*/ uint16(x86_xArgXmm2M128),
+ /*4497*/ uint16(x86_xMatch),
+ /*4498*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4510,
+ 0x0, 4504,
+ /*4504*/ uint16(x86_xSetOp), uint16(x86_PACKUSWB),
+ /*4506*/ uint16(x86_xReadSlashR),
+ /*4507*/ uint16(x86_xArgMm),
+ /*4508*/ uint16(x86_xArgMmM64),
+ /*4509*/ uint16(x86_xMatch),
+ /*4510*/ uint16(x86_xSetOp), uint16(x86_PACKUSWB),
+ /*4512*/ uint16(x86_xReadSlashR),
+ /*4513*/ uint16(x86_xArgXmm1),
+ /*4514*/ uint16(x86_xArgXmm2M128),
+ /*4515*/ uint16(x86_xMatch),
+ /*4516*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4528,
+ 0x0, 4522,
+ /*4522*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHBW),
+ /*4524*/ uint16(x86_xReadSlashR),
+ /*4525*/ uint16(x86_xArgMm),
+ /*4526*/ uint16(x86_xArgMmM64),
+ /*4527*/ uint16(x86_xMatch),
+ /*4528*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHBW),
+ /*4530*/ uint16(x86_xReadSlashR),
+ /*4531*/ uint16(x86_xArgXmm1),
+ /*4532*/ uint16(x86_xArgXmm2M128),
+ /*4533*/ uint16(x86_xMatch),
+ /*4534*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4546,
+ 0x0, 4540,
+ /*4540*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHWD),
+ /*4542*/ uint16(x86_xReadSlashR),
+ /*4543*/ uint16(x86_xArgMm),
+ /*4544*/ uint16(x86_xArgMmM64),
+ /*4545*/ uint16(x86_xMatch),
+ /*4546*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHWD),
+ /*4548*/ uint16(x86_xReadSlashR),
+ /*4549*/ uint16(x86_xArgXmm1),
+ /*4550*/ uint16(x86_xArgXmm2M128),
+ /*4551*/ uint16(x86_xMatch),
+ /*4552*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4564,
+ 0x0, 4558,
+ /*4558*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHDQ),
+ /*4560*/ uint16(x86_xReadSlashR),
+ /*4561*/ uint16(x86_xArgMm),
+ /*4562*/ uint16(x86_xArgMmM64),
+ /*4563*/ uint16(x86_xMatch),
+ /*4564*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHDQ),
+ /*4566*/ uint16(x86_xReadSlashR),
+ /*4567*/ uint16(x86_xArgXmm1),
+ /*4568*/ uint16(x86_xArgXmm2M128),
+ /*4569*/ uint16(x86_xMatch),
+ /*4570*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4582,
+ 0x0, 4576,
+ /*4576*/ uint16(x86_xSetOp), uint16(x86_PACKSSDW),
+ /*4578*/ uint16(x86_xReadSlashR),
+ /*4579*/ uint16(x86_xArgMm1),
+ /*4580*/ uint16(x86_xArgMm2M64),
+ /*4581*/ uint16(x86_xMatch),
+ /*4582*/ uint16(x86_xSetOp), uint16(x86_PACKSSDW),
+ /*4584*/ uint16(x86_xReadSlashR),
+ /*4585*/ uint16(x86_xArgXmm1),
+ /*4586*/ uint16(x86_xArgXmm2M128),
+ /*4587*/ uint16(x86_xMatch),
+ /*4588*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 4592,
+ /*4592*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLQDQ),
+ /*4594*/ uint16(x86_xReadSlashR),
+ /*4595*/ uint16(x86_xArgXmm1),
+ /*4596*/ uint16(x86_xArgXmm2M128),
+ /*4597*/ uint16(x86_xMatch),
+ /*4598*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 4602,
+ /*4602*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHQDQ),
+ /*4604*/ uint16(x86_xReadSlashR),
+ /*4605*/ uint16(x86_xArgXmm1),
+ /*4606*/ uint16(x86_xArgXmm2M128),
+ /*4607*/ uint16(x86_xMatch),
+ /*4608*/ uint16(x86_xCondIs64), 4611, 4649,
+ /*4611*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4633,
+ 0x0, 4617,
+ /*4617*/ uint16(x86_xCondDataSize), 4621, 4627, 0,
+ /*4621*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*4623*/ uint16(x86_xReadSlashR),
+ /*4624*/ uint16(x86_xArgMm),
+ /*4625*/ uint16(x86_xArgRM32),
+ /*4626*/ uint16(x86_xMatch),
+ /*4627*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*4629*/ uint16(x86_xReadSlashR),
+ /*4630*/ uint16(x86_xArgMm),
+ /*4631*/ uint16(x86_xArgRM32),
+ /*4632*/ uint16(x86_xMatch),
+ /*4633*/ uint16(x86_xCondDataSize), 4637, 4643, 0,
+ /*4637*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*4639*/ uint16(x86_xReadSlashR),
+ /*4640*/ uint16(x86_xArgXmm),
+ /*4641*/ uint16(x86_xArgRM32),
+ /*4642*/ uint16(x86_xMatch),
+ /*4643*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*4645*/ uint16(x86_xReadSlashR),
+ /*4646*/ uint16(x86_xArgXmm),
+ /*4647*/ uint16(x86_xArgRM32),
+ /*4648*/ uint16(x86_xMatch),
+ /*4649*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4665,
+ 0x0, 4655,
+ /*4655*/ uint16(x86_xCondDataSize), 4621, 4627, 4659,
+ /*4659*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*4661*/ uint16(x86_xReadSlashR),
+ /*4662*/ uint16(x86_xArgMm),
+ /*4663*/ uint16(x86_xArgRM64),
+ /*4664*/ uint16(x86_xMatch),
+ /*4665*/ uint16(x86_xCondDataSize), 4637, 4643, 4669,
+ /*4669*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*4671*/ uint16(x86_xReadSlashR),
+ /*4672*/ uint16(x86_xArgXmm),
+ /*4673*/ uint16(x86_xArgRM64),
+ /*4674*/ uint16(x86_xMatch),
+ /*4675*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 4695,
+ 0x66, 4689,
+ 0x0, 4683,
+ /*4683*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*4685*/ uint16(x86_xReadSlashR),
+ /*4686*/ uint16(x86_xArgMm),
+ /*4687*/ uint16(x86_xArgMmM64),
+ /*4688*/ uint16(x86_xMatch),
+ /*4689*/ uint16(x86_xSetOp), uint16(x86_MOVDQA),
+ /*4691*/ uint16(x86_xReadSlashR),
+ /*4692*/ uint16(x86_xArgXmm1),
+ /*4693*/ uint16(x86_xArgXmm2M128),
+ /*4694*/ uint16(x86_xMatch),
+ /*4695*/ uint16(x86_xSetOp), uint16(x86_MOVDQU),
+ /*4697*/ uint16(x86_xReadSlashR),
+ /*4698*/ uint16(x86_xArgXmm1),
+ /*4699*/ uint16(x86_xArgXmm2M128),
+ /*4700*/ uint16(x86_xMatch),
+ /*4701*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 4735,
+ 0xF2, 4727,
+ 0x66, 4719,
+ 0x0, 4711,
+ /*4711*/ uint16(x86_xSetOp), uint16(x86_PSHUFW),
+ /*4713*/ uint16(x86_xReadSlashR),
+ /*4714*/ uint16(x86_xReadIb),
+ /*4715*/ uint16(x86_xArgMm1),
+ /*4716*/ uint16(x86_xArgMm2M64),
+ /*4717*/ uint16(x86_xArgImm8u),
+ /*4718*/ uint16(x86_xMatch),
+ /*4719*/ uint16(x86_xSetOp), uint16(x86_PSHUFD),
+ /*4721*/ uint16(x86_xReadSlashR),
+ /*4722*/ uint16(x86_xReadIb),
+ /*4723*/ uint16(x86_xArgXmm1),
+ /*4724*/ uint16(x86_xArgXmm2M128),
+ /*4725*/ uint16(x86_xArgImm8u),
+ /*4726*/ uint16(x86_xMatch),
+ /*4727*/ uint16(x86_xSetOp), uint16(x86_PSHUFLW),
+ /*4729*/ uint16(x86_xReadSlashR),
+ /*4730*/ uint16(x86_xReadIb),
+ /*4731*/ uint16(x86_xArgXmm1),
+ /*4732*/ uint16(x86_xArgXmm2M128),
+ /*4733*/ uint16(x86_xArgImm8u),
+ /*4734*/ uint16(x86_xMatch),
+ /*4735*/ uint16(x86_xSetOp), uint16(x86_PSHUFHW),
+ /*4737*/ uint16(x86_xReadSlashR),
+ /*4738*/ uint16(x86_xReadIb),
+ /*4739*/ uint16(x86_xArgXmm1),
+ /*4740*/ uint16(x86_xArgXmm2M128),
+ /*4741*/ uint16(x86_xArgImm8u),
+ /*4742*/ uint16(x86_xMatch),
+ /*4743*/ uint16(x86_xCondSlashR),
+ 0, // 0
+ 0, // 1
+ 4752, // 2
+ 0, // 3
+ 4770, // 4
+ 0, // 5
+ 4788, // 6
+ 0, // 7
+ /*4752*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4764,
+ 0x0, 4758,
+ /*4758*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
+ /*4760*/ uint16(x86_xReadIb),
+ /*4761*/ uint16(x86_xArgMm2),
+ /*4762*/ uint16(x86_xArgImm8u),
+ /*4763*/ uint16(x86_xMatch),
+ /*4764*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
+ /*4766*/ uint16(x86_xReadIb),
+ /*4767*/ uint16(x86_xArgXmm2),
+ /*4768*/ uint16(x86_xArgImm8u),
+ /*4769*/ uint16(x86_xMatch),
+ /*4770*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4782,
+ 0x0, 4776,
+ /*4776*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
+ /*4778*/ uint16(x86_xReadIb),
+ /*4779*/ uint16(x86_xArgMm2),
+ /*4780*/ uint16(x86_xArgImm8u),
+ /*4781*/ uint16(x86_xMatch),
+ /*4782*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
+ /*4784*/ uint16(x86_xReadIb),
+ /*4785*/ uint16(x86_xArgXmm2),
+ /*4786*/ uint16(x86_xArgImm8u),
+ /*4787*/ uint16(x86_xMatch),
+ /*4788*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4800,
+ 0x0, 4794,
+ /*4794*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
+ /*4796*/ uint16(x86_xReadIb),
+ /*4797*/ uint16(x86_xArgMm2),
+ /*4798*/ uint16(x86_xArgImm8u),
+ /*4799*/ uint16(x86_xMatch),
+ /*4800*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
+ /*4802*/ uint16(x86_xReadIb),
+ /*4803*/ uint16(x86_xArgXmm2),
+ /*4804*/ uint16(x86_xArgImm8u),
+ /*4805*/ uint16(x86_xMatch),
+ /*4806*/ uint16(x86_xCondSlashR),
+ 0, // 0
+ 0, // 1
+ 4815, // 2
+ 0, // 3
+ 4833, // 4
+ 0, // 5
+ 4851, // 6
+ 0, // 7
+ /*4815*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4827,
+ 0x0, 4821,
+ /*4821*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
+ /*4823*/ uint16(x86_xReadIb),
+ /*4824*/ uint16(x86_xArgMm2),
+ /*4825*/ uint16(x86_xArgImm8u),
+ /*4826*/ uint16(x86_xMatch),
+ /*4827*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
+ /*4829*/ uint16(x86_xReadIb),
+ /*4830*/ uint16(x86_xArgXmm2),
+ /*4831*/ uint16(x86_xArgImm8u),
+ /*4832*/ uint16(x86_xMatch),
+ /*4833*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4845,
+ 0x0, 4839,
+ /*4839*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
+ /*4841*/ uint16(x86_xReadIb),
+ /*4842*/ uint16(x86_xArgMm2),
+ /*4843*/ uint16(x86_xArgImm8u),
+ /*4844*/ uint16(x86_xMatch),
+ /*4845*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
+ /*4847*/ uint16(x86_xReadIb),
+ /*4848*/ uint16(x86_xArgXmm2),
+ /*4849*/ uint16(x86_xArgImm8u),
+ /*4850*/ uint16(x86_xMatch),
+ /*4851*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4863,
+ 0x0, 4857,
+ /*4857*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
+ /*4859*/ uint16(x86_xReadIb),
+ /*4860*/ uint16(x86_xArgMm2),
+ /*4861*/ uint16(x86_xArgImm8u),
+ /*4862*/ uint16(x86_xMatch),
+ /*4863*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
+ /*4865*/ uint16(x86_xReadIb),
+ /*4866*/ uint16(x86_xArgXmm2),
+ /*4867*/ uint16(x86_xArgImm8u),
+ /*4868*/ uint16(x86_xMatch),
+ /*4869*/ uint16(x86_xCondSlashR),
+ 0, // 0
+ 0, // 1
+ 4878, // 2
+ 4896, // 3
+ 0, // 4
+ 0, // 5
+ 4906, // 6
+ 4924, // 7
+ /*4878*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4890,
+ 0x0, 4884,
+ /*4884*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
+ /*4886*/ uint16(x86_xReadIb),
+ /*4887*/ uint16(x86_xArgMm2),
+ /*4888*/ uint16(x86_xArgImm8u),
+ /*4889*/ uint16(x86_xMatch),
+ /*4890*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
+ /*4892*/ uint16(x86_xReadIb),
+ /*4893*/ uint16(x86_xArgXmm2),
+ /*4894*/ uint16(x86_xArgImm8u),
+ /*4895*/ uint16(x86_xMatch),
+ /*4896*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 4900,
+ /*4900*/ uint16(x86_xSetOp), uint16(x86_PSRLDQ),
+ /*4902*/ uint16(x86_xReadIb),
+ /*4903*/ uint16(x86_xArgXmm2),
+ /*4904*/ uint16(x86_xArgImm8u),
+ /*4905*/ uint16(x86_xMatch),
+ /*4906*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4918,
+ 0x0, 4912,
+ /*4912*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
+ /*4914*/ uint16(x86_xReadIb),
+ /*4915*/ uint16(x86_xArgMm2),
+ /*4916*/ uint16(x86_xArgImm8u),
+ /*4917*/ uint16(x86_xMatch),
+ /*4918*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
+ /*4920*/ uint16(x86_xReadIb),
+ /*4921*/ uint16(x86_xArgXmm2),
+ /*4922*/ uint16(x86_xArgImm8u),
+ /*4923*/ uint16(x86_xMatch),
+ /*4924*/ uint16(x86_xCondPrefix), 1,
+ 0x66, 4928,
+ /*4928*/ uint16(x86_xSetOp), uint16(x86_PSLLDQ),
+ /*4930*/ uint16(x86_xReadIb),
+ /*4931*/ uint16(x86_xArgXmm2),
+ /*4932*/ uint16(x86_xArgImm8u),
+ /*4933*/ uint16(x86_xMatch),
+ /*4934*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4946,
+ 0x0, 4940,
+ /*4940*/ uint16(x86_xSetOp), uint16(x86_PCMPEQB),
+ /*4942*/ uint16(x86_xReadSlashR),
+ /*4943*/ uint16(x86_xArgMm),
+ /*4944*/ uint16(x86_xArgMmM64),
+ /*4945*/ uint16(x86_xMatch),
+ /*4946*/ uint16(x86_xSetOp), uint16(x86_PCMPEQB),
+ /*4948*/ uint16(x86_xReadSlashR),
+ /*4949*/ uint16(x86_xArgXmm1),
+ /*4950*/ uint16(x86_xArgXmm2M128),
+ /*4951*/ uint16(x86_xMatch),
+ /*4952*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4964,
+ 0x0, 4958,
+ /*4958*/ uint16(x86_xSetOp), uint16(x86_PCMPEQW),
+ /*4960*/ uint16(x86_xReadSlashR),
+ /*4961*/ uint16(x86_xArgMm),
+ /*4962*/ uint16(x86_xArgMmM64),
+ /*4963*/ uint16(x86_xMatch),
+ /*4964*/ uint16(x86_xSetOp), uint16(x86_PCMPEQW),
+ /*4966*/ uint16(x86_xReadSlashR),
+ /*4967*/ uint16(x86_xArgXmm1),
+ /*4968*/ uint16(x86_xArgXmm2M128),
+ /*4969*/ uint16(x86_xMatch),
+ /*4970*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 4982,
+ 0x0, 4976,
+ /*4976*/ uint16(x86_xSetOp), uint16(x86_PCMPEQD),
+ /*4978*/ uint16(x86_xReadSlashR),
+ /*4979*/ uint16(x86_xArgMm),
+ /*4980*/ uint16(x86_xArgMmM64),
+ /*4981*/ uint16(x86_xMatch),
+ /*4982*/ uint16(x86_xSetOp), uint16(x86_PCMPEQD),
+ /*4984*/ uint16(x86_xReadSlashR),
+ /*4985*/ uint16(x86_xArgXmm1),
+ /*4986*/ uint16(x86_xArgXmm2M128),
+ /*4987*/ uint16(x86_xMatch),
+ /*4988*/ uint16(x86_xSetOp), uint16(x86_EMMS),
+ /*4990*/ uint16(x86_xMatch),
+ /*4991*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 5003,
+ 0x66, 4997,
+ /*4997*/ uint16(x86_xSetOp), uint16(x86_HADDPD),
+ /*4999*/ uint16(x86_xReadSlashR),
+ /*5000*/ uint16(x86_xArgXmm1),
+ /*5001*/ uint16(x86_xArgXmm2M128),
+ /*5002*/ uint16(x86_xMatch),
+ /*5003*/ uint16(x86_xSetOp), uint16(x86_HADDPS),
+ /*5005*/ uint16(x86_xReadSlashR),
+ /*5006*/ uint16(x86_xArgXmm1),
+ /*5007*/ uint16(x86_xArgXmm2M128),
+ /*5008*/ uint16(x86_xMatch),
+ /*5009*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 5021,
+ 0x66, 5015,
+ /*5015*/ uint16(x86_xSetOp), uint16(x86_HSUBPD),
+ /*5017*/ uint16(x86_xReadSlashR),
+ /*5018*/ uint16(x86_xArgXmm1),
+ /*5019*/ uint16(x86_xArgXmm2M128),
+ /*5020*/ uint16(x86_xMatch),
+ /*5021*/ uint16(x86_xSetOp), uint16(x86_HSUBPS),
+ /*5023*/ uint16(x86_xReadSlashR),
+ /*5024*/ uint16(x86_xArgXmm1),
+ /*5025*/ uint16(x86_xArgXmm2M128),
+ /*5026*/ uint16(x86_xMatch),
+ /*5027*/ uint16(x86_xCondIs64), 5030, 5076,
+ /*5030*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 5070,
+ 0x66, 5054,
+ 0x0, 5038,
+ /*5038*/ uint16(x86_xCondDataSize), 5042, 5048, 0,
+ /*5042*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*5044*/ uint16(x86_xReadSlashR),
+ /*5045*/ uint16(x86_xArgRM32),
+ /*5046*/ uint16(x86_xArgMm),
+ /*5047*/ uint16(x86_xMatch),
+ /*5048*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*5050*/ uint16(x86_xReadSlashR),
+ /*5051*/ uint16(x86_xArgRM32),
+ /*5052*/ uint16(x86_xArgMm),
+ /*5053*/ uint16(x86_xMatch),
+ /*5054*/ uint16(x86_xCondDataSize), 5058, 5064, 0,
+ /*5058*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*5060*/ uint16(x86_xReadSlashR),
+ /*5061*/ uint16(x86_xArgRM32),
+ /*5062*/ uint16(x86_xArgXmm),
+ /*5063*/ uint16(x86_xMatch),
+ /*5064*/ uint16(x86_xSetOp), uint16(x86_MOVD),
+ /*5066*/ uint16(x86_xReadSlashR),
+ /*5067*/ uint16(x86_xArgRM32),
+ /*5068*/ uint16(x86_xArgXmm),
+ /*5069*/ uint16(x86_xMatch),
+ /*5070*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*5072*/ uint16(x86_xReadSlashR),
+ /*5073*/ uint16(x86_xArgXmm1),
+ /*5074*/ uint16(x86_xArgXmm2M64),
+ /*5075*/ uint16(x86_xMatch),
+ /*5076*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 5070,
+ 0x66, 5094,
+ 0x0, 5084,
+ /*5084*/ uint16(x86_xCondDataSize), 5042, 5048, 5088,
+ /*5088*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*5090*/ uint16(x86_xReadSlashR),
+ /*5091*/ uint16(x86_xArgRM64),
+ /*5092*/ uint16(x86_xArgMm),
+ /*5093*/ uint16(x86_xMatch),
+ /*5094*/ uint16(x86_xCondDataSize), 5058, 5064, 5098,
+ /*5098*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*5100*/ uint16(x86_xReadSlashR),
+ /*5101*/ uint16(x86_xArgRM64),
+ /*5102*/ uint16(x86_xArgXmm),
+ /*5103*/ uint16(x86_xMatch),
+ /*5104*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 5124,
+ 0x66, 5118,
+ 0x0, 5112,
+ /*5112*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*5114*/ uint16(x86_xReadSlashR),
+ /*5115*/ uint16(x86_xArgMmM64),
+ /*5116*/ uint16(x86_xArgMm),
+ /*5117*/ uint16(x86_xMatch),
+ /*5118*/ uint16(x86_xSetOp), uint16(x86_MOVDQA),
+ /*5120*/ uint16(x86_xReadSlashR),
+ /*5121*/ uint16(x86_xArgXmm2M128),
+ /*5122*/ uint16(x86_xArgXmm1),
+ /*5123*/ uint16(x86_xMatch),
+ /*5124*/ uint16(x86_xSetOp), uint16(x86_MOVDQU),
+ /*5126*/ uint16(x86_xReadSlashR),
+ /*5127*/ uint16(x86_xArgXmm2M128),
+ /*5128*/ uint16(x86_xArgXmm1),
+ /*5129*/ uint16(x86_xMatch),
+ /*5130*/ uint16(x86_xCondIs64), 5133, 5147,
+ /*5133*/ uint16(x86_xCondDataSize), 5137, 5142, 0,
+ /*5137*/ uint16(x86_xSetOp), uint16(x86_JO),
+ /*5139*/ uint16(x86_xReadCw),
+ /*5140*/ uint16(x86_xArgRel16),
+ /*5141*/ uint16(x86_xMatch),
+ /*5142*/ uint16(x86_xSetOp), uint16(x86_JO),
+ /*5144*/ uint16(x86_xReadCd),
+ /*5145*/ uint16(x86_xArgRel32),
+ /*5146*/ uint16(x86_xMatch),
+ /*5147*/ uint16(x86_xCondDataSize), 5151, 5142, 5156,
+ /*5151*/ uint16(x86_xSetOp), uint16(x86_JO),
+ /*5153*/ uint16(x86_xReadCd),
+ /*5154*/ uint16(x86_xArgRel32),
+ /*5155*/ uint16(x86_xMatch),
+ /*5156*/ uint16(x86_xSetOp), uint16(x86_JO),
+ /*5158*/ uint16(x86_xReadCd),
+ /*5159*/ uint16(x86_xArgRel32),
+ /*5160*/ uint16(x86_xMatch),
+ /*5161*/ uint16(x86_xCondIs64), 5164, 5178,
+ /*5164*/ uint16(x86_xCondDataSize), 5168, 5173, 0,
+ /*5168*/ uint16(x86_xSetOp), uint16(x86_JNO),
+ /*5170*/ uint16(x86_xReadCw),
+ /*5171*/ uint16(x86_xArgRel16),
+ /*5172*/ uint16(x86_xMatch),
+ /*5173*/ uint16(x86_xSetOp), uint16(x86_JNO),
+ /*5175*/ uint16(x86_xReadCd),
+ /*5176*/ uint16(x86_xArgRel32),
+ /*5177*/ uint16(x86_xMatch),
+ /*5178*/ uint16(x86_xCondDataSize), 5182, 5173, 5187,
+ /*5182*/ uint16(x86_xSetOp), uint16(x86_JNO),
+ /*5184*/ uint16(x86_xReadCd),
+ /*5185*/ uint16(x86_xArgRel32),
+ /*5186*/ uint16(x86_xMatch),
+ /*5187*/ uint16(x86_xSetOp), uint16(x86_JNO),
+ /*5189*/ uint16(x86_xReadCd),
+ /*5190*/ uint16(x86_xArgRel32),
+ /*5191*/ uint16(x86_xMatch),
+ /*5192*/ uint16(x86_xCondIs64), 5195, 5209,
+ /*5195*/ uint16(x86_xCondDataSize), 5199, 5204, 0,
+ /*5199*/ uint16(x86_xSetOp), uint16(x86_JB),
+ /*5201*/ uint16(x86_xReadCw),
+ /*5202*/ uint16(x86_xArgRel16),
+ /*5203*/ uint16(x86_xMatch),
+ /*5204*/ uint16(x86_xSetOp), uint16(x86_JB),
+ /*5206*/ uint16(x86_xReadCd),
+ /*5207*/ uint16(x86_xArgRel32),
+ /*5208*/ uint16(x86_xMatch),
+ /*5209*/ uint16(x86_xCondDataSize), 5213, 5204, 5218,
+ /*5213*/ uint16(x86_xSetOp), uint16(x86_JB),
+ /*5215*/ uint16(x86_xReadCd),
+ /*5216*/ uint16(x86_xArgRel32),
+ /*5217*/ uint16(x86_xMatch),
+ /*5218*/ uint16(x86_xSetOp), uint16(x86_JB),
+ /*5220*/ uint16(x86_xReadCd),
+ /*5221*/ uint16(x86_xArgRel32),
+ /*5222*/ uint16(x86_xMatch),
+ /*5223*/ uint16(x86_xCondIs64), 5226, 5240,
+ /*5226*/ uint16(x86_xCondDataSize), 5230, 5235, 0,
+ /*5230*/ uint16(x86_xSetOp), uint16(x86_JAE),
+ /*5232*/ uint16(x86_xReadCw),
+ /*5233*/ uint16(x86_xArgRel16),
+ /*5234*/ uint16(x86_xMatch),
+ /*5235*/ uint16(x86_xSetOp), uint16(x86_JAE),
+ /*5237*/ uint16(x86_xReadCd),
+ /*5238*/ uint16(x86_xArgRel32),
+ /*5239*/ uint16(x86_xMatch),
+ /*5240*/ uint16(x86_xCondDataSize), 5244, 5235, 5249,
+ /*5244*/ uint16(x86_xSetOp), uint16(x86_JAE),
+ /*5246*/ uint16(x86_xReadCd),
+ /*5247*/ uint16(x86_xArgRel32),
+ /*5248*/ uint16(x86_xMatch),
+ /*5249*/ uint16(x86_xSetOp), uint16(x86_JAE),
+ /*5251*/ uint16(x86_xReadCd),
+ /*5252*/ uint16(x86_xArgRel32),
+ /*5253*/ uint16(x86_xMatch),
+ /*5254*/ uint16(x86_xCondIs64), 5257, 5271,
+ /*5257*/ uint16(x86_xCondDataSize), 5261, 5266, 0,
+ /*5261*/ uint16(x86_xSetOp), uint16(x86_JE),
+ /*5263*/ uint16(x86_xReadCw),
+ /*5264*/ uint16(x86_xArgRel16),
+ /*5265*/ uint16(x86_xMatch),
+ /*5266*/ uint16(x86_xSetOp), uint16(x86_JE),
+ /*5268*/ uint16(x86_xReadCd),
+ /*5269*/ uint16(x86_xArgRel32),
+ /*5270*/ uint16(x86_xMatch),
+ /*5271*/ uint16(x86_xCondDataSize), 5275, 5266, 5280,
+ /*5275*/ uint16(x86_xSetOp), uint16(x86_JE),
+ /*5277*/ uint16(x86_xReadCd),
+ /*5278*/ uint16(x86_xArgRel32),
+ /*5279*/ uint16(x86_xMatch),
+ /*5280*/ uint16(x86_xSetOp), uint16(x86_JE),
+ /*5282*/ uint16(x86_xReadCd),
+ /*5283*/ uint16(x86_xArgRel32),
+ /*5284*/ uint16(x86_xMatch),
+ /*5285*/ uint16(x86_xCondIs64), 5288, 5302,
+ /*5288*/ uint16(x86_xCondDataSize), 5292, 5297, 0,
+ /*5292*/ uint16(x86_xSetOp), uint16(x86_JNE),
+ /*5294*/ uint16(x86_xReadCw),
+ /*5295*/ uint16(x86_xArgRel16),
+ /*5296*/ uint16(x86_xMatch),
+ /*5297*/ uint16(x86_xSetOp), uint16(x86_JNE),
+ /*5299*/ uint16(x86_xReadCd),
+ /*5300*/ uint16(x86_xArgRel32),
+ /*5301*/ uint16(x86_xMatch),
+ /*5302*/ uint16(x86_xCondDataSize), 5306, 5297, 5311,
+ /*5306*/ uint16(x86_xSetOp), uint16(x86_JNE),
+ /*5308*/ uint16(x86_xReadCd),
+ /*5309*/ uint16(x86_xArgRel32),
+ /*5310*/ uint16(x86_xMatch),
+ /*5311*/ uint16(x86_xSetOp), uint16(x86_JNE),
+ /*5313*/ uint16(x86_xReadCd),
+ /*5314*/ uint16(x86_xArgRel32),
+ /*5315*/ uint16(x86_xMatch),
+ /*5316*/ uint16(x86_xCondIs64), 5319, 5333,
+ /*5319*/ uint16(x86_xCondDataSize), 5323, 5328, 0,
+ /*5323*/ uint16(x86_xSetOp), uint16(x86_JBE),
+ /*5325*/ uint16(x86_xReadCw),
+ /*5326*/ uint16(x86_xArgRel16),
+ /*5327*/ uint16(x86_xMatch),
+ /*5328*/ uint16(x86_xSetOp), uint16(x86_JBE),
+ /*5330*/ uint16(x86_xReadCd),
+ /*5331*/ uint16(x86_xArgRel32),
+ /*5332*/ uint16(x86_xMatch),
+ /*5333*/ uint16(x86_xCondDataSize), 5337, 5328, 5342,
+ /*5337*/ uint16(x86_xSetOp), uint16(x86_JBE),
+ /*5339*/ uint16(x86_xReadCd),
+ /*5340*/ uint16(x86_xArgRel32),
+ /*5341*/ uint16(x86_xMatch),
+ /*5342*/ uint16(x86_xSetOp), uint16(x86_JBE),
+ /*5344*/ uint16(x86_xReadCd),
+ /*5345*/ uint16(x86_xArgRel32),
+ /*5346*/ uint16(x86_xMatch),
+ /*5347*/ uint16(x86_xCondIs64), 5350, 5364,
+ /*5350*/ uint16(x86_xCondDataSize), 5354, 5359, 0,
+ /*5354*/ uint16(x86_xSetOp), uint16(x86_JA),
+ /*5356*/ uint16(x86_xReadCw),
+ /*5357*/ uint16(x86_xArgRel16),
+ /*5358*/ uint16(x86_xMatch),
+ /*5359*/ uint16(x86_xSetOp), uint16(x86_JA),
+ /*5361*/ uint16(x86_xReadCd),
+ /*5362*/ uint16(x86_xArgRel32),
+ /*5363*/ uint16(x86_xMatch),
+ /*5364*/ uint16(x86_xCondDataSize), 5368, 5359, 5373,
+ /*5368*/ uint16(x86_xSetOp), uint16(x86_JA),
+ /*5370*/ uint16(x86_xReadCd),
+ /*5371*/ uint16(x86_xArgRel32),
+ /*5372*/ uint16(x86_xMatch),
+ /*5373*/ uint16(x86_xSetOp), uint16(x86_JA),
+ /*5375*/ uint16(x86_xReadCd),
+ /*5376*/ uint16(x86_xArgRel32),
+ /*5377*/ uint16(x86_xMatch),
+ /*5378*/ uint16(x86_xCondIs64), 5381, 5395,
+ /*5381*/ uint16(x86_xCondDataSize), 5385, 5390, 0,
+ /*5385*/ uint16(x86_xSetOp), uint16(x86_JS),
+ /*5387*/ uint16(x86_xReadCw),
+ /*5388*/ uint16(x86_xArgRel16),
+ /*5389*/ uint16(x86_xMatch),
+ /*5390*/ uint16(x86_xSetOp), uint16(x86_JS),
+ /*5392*/ uint16(x86_xReadCd),
+ /*5393*/ uint16(x86_xArgRel32),
+ /*5394*/ uint16(x86_xMatch),
+ /*5395*/ uint16(x86_xCondDataSize), 5399, 5390, 5404,
+ /*5399*/ uint16(x86_xSetOp), uint16(x86_JS),
+ /*5401*/ uint16(x86_xReadCd),
+ /*5402*/ uint16(x86_xArgRel32),
+ /*5403*/ uint16(x86_xMatch),
+ /*5404*/ uint16(x86_xSetOp), uint16(x86_JS),
+ /*5406*/ uint16(x86_xReadCd),
+ /*5407*/ uint16(x86_xArgRel32),
+ /*5408*/ uint16(x86_xMatch),
+ /*5409*/ uint16(x86_xCondIs64), 5412, 5426,
+ /*5412*/ uint16(x86_xCondDataSize), 5416, 5421, 0,
+ /*5416*/ uint16(x86_xSetOp), uint16(x86_JNS),
+ /*5418*/ uint16(x86_xReadCw),
+ /*5419*/ uint16(x86_xArgRel16),
+ /*5420*/ uint16(x86_xMatch),
+ /*5421*/ uint16(x86_xSetOp), uint16(x86_JNS),
+ /*5423*/ uint16(x86_xReadCd),
+ /*5424*/ uint16(x86_xArgRel32),
+ /*5425*/ uint16(x86_xMatch),
+ /*5426*/ uint16(x86_xCondDataSize), 5430, 5421, 5435,
+ /*5430*/ uint16(x86_xSetOp), uint16(x86_JNS),
+ /*5432*/ uint16(x86_xReadCd),
+ /*5433*/ uint16(x86_xArgRel32),
+ /*5434*/ uint16(x86_xMatch),
+ /*5435*/ uint16(x86_xSetOp), uint16(x86_JNS),
+ /*5437*/ uint16(x86_xReadCd),
+ /*5438*/ uint16(x86_xArgRel32),
+ /*5439*/ uint16(x86_xMatch),
+ /*5440*/ uint16(x86_xCondIs64), 5443, 5457,
+ /*5443*/ uint16(x86_xCondDataSize), 5447, 5452, 0,
+ /*5447*/ uint16(x86_xSetOp), uint16(x86_JP),
+ /*5449*/ uint16(x86_xReadCw),
+ /*5450*/ uint16(x86_xArgRel16),
+ /*5451*/ uint16(x86_xMatch),
+ /*5452*/ uint16(x86_xSetOp), uint16(x86_JP),
+ /*5454*/ uint16(x86_xReadCd),
+ /*5455*/ uint16(x86_xArgRel32),
+ /*5456*/ uint16(x86_xMatch),
+ /*5457*/ uint16(x86_xCondDataSize), 5461, 5452, 5466,
+ /*5461*/ uint16(x86_xSetOp), uint16(x86_JP),
+ /*5463*/ uint16(x86_xReadCd),
+ /*5464*/ uint16(x86_xArgRel32),
+ /*5465*/ uint16(x86_xMatch),
+ /*5466*/ uint16(x86_xSetOp), uint16(x86_JP),
+ /*5468*/ uint16(x86_xReadCd),
+ /*5469*/ uint16(x86_xArgRel32),
+ /*5470*/ uint16(x86_xMatch),
+ /*5471*/ uint16(x86_xCondIs64), 5474, 5488,
+ /*5474*/ uint16(x86_xCondDataSize), 5478, 5483, 0,
+ /*5478*/ uint16(x86_xSetOp), uint16(x86_JNP),
+ /*5480*/ uint16(x86_xReadCw),
+ /*5481*/ uint16(x86_xArgRel16),
+ /*5482*/ uint16(x86_xMatch),
+ /*5483*/ uint16(x86_xSetOp), uint16(x86_JNP),
+ /*5485*/ uint16(x86_xReadCd),
+ /*5486*/ uint16(x86_xArgRel32),
+ /*5487*/ uint16(x86_xMatch),
+ /*5488*/ uint16(x86_xCondDataSize), 5492, 5483, 5497,
+ /*5492*/ uint16(x86_xSetOp), uint16(x86_JNP),
+ /*5494*/ uint16(x86_xReadCd),
+ /*5495*/ uint16(x86_xArgRel32),
+ /*5496*/ uint16(x86_xMatch),
+ /*5497*/ uint16(x86_xSetOp), uint16(x86_JNP),
+ /*5499*/ uint16(x86_xReadCd),
+ /*5500*/ uint16(x86_xArgRel32),
+ /*5501*/ uint16(x86_xMatch),
+ /*5502*/ uint16(x86_xCondIs64), 5505, 5519,
+ /*5505*/ uint16(x86_xCondDataSize), 5509, 5514, 0,
+ /*5509*/ uint16(x86_xSetOp), uint16(x86_JL),
+ /*5511*/ uint16(x86_xReadCw),
+ /*5512*/ uint16(x86_xArgRel16),
+ /*5513*/ uint16(x86_xMatch),
+ /*5514*/ uint16(x86_xSetOp), uint16(x86_JL),
+ /*5516*/ uint16(x86_xReadCd),
+ /*5517*/ uint16(x86_xArgRel32),
+ /*5518*/ uint16(x86_xMatch),
+ /*5519*/ uint16(x86_xCondDataSize), 5523, 5514, 5528,
+ /*5523*/ uint16(x86_xSetOp), uint16(x86_JL),
+ /*5525*/ uint16(x86_xReadCd),
+ /*5526*/ uint16(x86_xArgRel32),
+ /*5527*/ uint16(x86_xMatch),
+ /*5528*/ uint16(x86_xSetOp), uint16(x86_JL),
+ /*5530*/ uint16(x86_xReadCd),
+ /*5531*/ uint16(x86_xArgRel32),
+ /*5532*/ uint16(x86_xMatch),
+ /*5533*/ uint16(x86_xCondIs64), 5536, 5550,
+ /*5536*/ uint16(x86_xCondDataSize), 5540, 5545, 0,
+ /*5540*/ uint16(x86_xSetOp), uint16(x86_JGE),
+ /*5542*/ uint16(x86_xReadCw),
+ /*5543*/ uint16(x86_xArgRel16),
+ /*5544*/ uint16(x86_xMatch),
+ /*5545*/ uint16(x86_xSetOp), uint16(x86_JGE),
+ /*5547*/ uint16(x86_xReadCd),
+ /*5548*/ uint16(x86_xArgRel32),
+ /*5549*/ uint16(x86_xMatch),
+ /*5550*/ uint16(x86_xCondDataSize), 5554, 5545, 5559,
+ /*5554*/ uint16(x86_xSetOp), uint16(x86_JGE),
+ /*5556*/ uint16(x86_xReadCd),
+ /*5557*/ uint16(x86_xArgRel32),
+ /*5558*/ uint16(x86_xMatch),
+ /*5559*/ uint16(x86_xSetOp), uint16(x86_JGE),
+ /*5561*/ uint16(x86_xReadCd),
+ /*5562*/ uint16(x86_xArgRel32),
+ /*5563*/ uint16(x86_xMatch),
+ /*5564*/ uint16(x86_xCondIs64), 5567, 5581,
+ /*5567*/ uint16(x86_xCondDataSize), 5571, 5576, 0,
+ /*5571*/ uint16(x86_xSetOp), uint16(x86_JLE),
+ /*5573*/ uint16(x86_xReadCw),
+ /*5574*/ uint16(x86_xArgRel16),
+ /*5575*/ uint16(x86_xMatch),
+ /*5576*/ uint16(x86_xSetOp), uint16(x86_JLE),
+ /*5578*/ uint16(x86_xReadCd),
+ /*5579*/ uint16(x86_xArgRel32),
+ /*5580*/ uint16(x86_xMatch),
+ /*5581*/ uint16(x86_xCondDataSize), 5585, 5576, 5590,
+ /*5585*/ uint16(x86_xSetOp), uint16(x86_JLE),
+ /*5587*/ uint16(x86_xReadCd),
+ /*5588*/ uint16(x86_xArgRel32),
+ /*5589*/ uint16(x86_xMatch),
+ /*5590*/ uint16(x86_xSetOp), uint16(x86_JLE),
+ /*5592*/ uint16(x86_xReadCd),
+ /*5593*/ uint16(x86_xArgRel32),
+ /*5594*/ uint16(x86_xMatch),
+ /*5595*/ uint16(x86_xCondIs64), 5598, 5612,
+ /*5598*/ uint16(x86_xCondDataSize), 5602, 5607, 0,
+ /*5602*/ uint16(x86_xSetOp), uint16(x86_JG),
+ /*5604*/ uint16(x86_xReadCw),
+ /*5605*/ uint16(x86_xArgRel16),
+ /*5606*/ uint16(x86_xMatch),
+ /*5607*/ uint16(x86_xSetOp), uint16(x86_JG),
+ /*5609*/ uint16(x86_xReadCd),
+ /*5610*/ uint16(x86_xArgRel32),
+ /*5611*/ uint16(x86_xMatch),
+ /*5612*/ uint16(x86_xCondDataSize), 5616, 5607, 5621,
+ /*5616*/ uint16(x86_xSetOp), uint16(x86_JG),
+ /*5618*/ uint16(x86_xReadCd),
+ /*5619*/ uint16(x86_xArgRel32),
+ /*5620*/ uint16(x86_xMatch),
+ /*5621*/ uint16(x86_xSetOp), uint16(x86_JG),
+ /*5623*/ uint16(x86_xReadCd),
+ /*5624*/ uint16(x86_xArgRel32),
+ /*5625*/ uint16(x86_xMatch),
+ /*5626*/ uint16(x86_xSetOp), uint16(x86_SETO),
+ /*5628*/ uint16(x86_xReadSlashR),
+ /*5629*/ uint16(x86_xArgRM8),
+ /*5630*/ uint16(x86_xMatch),
+ /*5631*/ uint16(x86_xSetOp), uint16(x86_SETNO),
+ /*5633*/ uint16(x86_xReadSlashR),
+ /*5634*/ uint16(x86_xArgRM8),
+ /*5635*/ uint16(x86_xMatch),
+ /*5636*/ uint16(x86_xSetOp), uint16(x86_SETB),
+ /*5638*/ uint16(x86_xReadSlashR),
+ /*5639*/ uint16(x86_xArgRM8),
+ /*5640*/ uint16(x86_xMatch),
+ /*5641*/ uint16(x86_xSetOp), uint16(x86_SETAE),
+ /*5643*/ uint16(x86_xReadSlashR),
+ /*5644*/ uint16(x86_xArgRM8),
+ /*5645*/ uint16(x86_xMatch),
+ /*5646*/ uint16(x86_xSetOp), uint16(x86_SETE),
+ /*5648*/ uint16(x86_xReadSlashR),
+ /*5649*/ uint16(x86_xArgRM8),
+ /*5650*/ uint16(x86_xMatch),
+ /*5651*/ uint16(x86_xSetOp), uint16(x86_SETNE),
+ /*5653*/ uint16(x86_xReadSlashR),
+ /*5654*/ uint16(x86_xArgRM8),
+ /*5655*/ uint16(x86_xMatch),
+ /*5656*/ uint16(x86_xSetOp), uint16(x86_SETBE),
+ /*5658*/ uint16(x86_xReadSlashR),
+ /*5659*/ uint16(x86_xArgRM8),
+ /*5660*/ uint16(x86_xMatch),
+ /*5661*/ uint16(x86_xSetOp), uint16(x86_SETA),
+ /*5663*/ uint16(x86_xReadSlashR),
+ /*5664*/ uint16(x86_xArgRM8),
+ /*5665*/ uint16(x86_xMatch),
+ /*5666*/ uint16(x86_xSetOp), uint16(x86_SETS),
+ /*5668*/ uint16(x86_xReadSlashR),
+ /*5669*/ uint16(x86_xArgRM8),
+ /*5670*/ uint16(x86_xMatch),
+ /*5671*/ uint16(x86_xSetOp), uint16(x86_SETNS),
+ /*5673*/ uint16(x86_xReadSlashR),
+ /*5674*/ uint16(x86_xArgRM8),
+ /*5675*/ uint16(x86_xMatch),
+ /*5676*/ uint16(x86_xSetOp), uint16(x86_SETP),
+ /*5678*/ uint16(x86_xReadSlashR),
+ /*5679*/ uint16(x86_xArgRM8),
+ /*5680*/ uint16(x86_xMatch),
+ /*5681*/ uint16(x86_xSetOp), uint16(x86_SETNP),
+ /*5683*/ uint16(x86_xReadSlashR),
+ /*5684*/ uint16(x86_xArgRM8),
+ /*5685*/ uint16(x86_xMatch),
+ /*5686*/ uint16(x86_xSetOp), uint16(x86_SETL),
+ /*5688*/ uint16(x86_xReadSlashR),
+ /*5689*/ uint16(x86_xArgRM8),
+ /*5690*/ uint16(x86_xMatch),
+ /*5691*/ uint16(x86_xSetOp), uint16(x86_SETGE),
+ /*5693*/ uint16(x86_xReadSlashR),
+ /*5694*/ uint16(x86_xArgRM8),
+ /*5695*/ uint16(x86_xMatch),
+ /*5696*/ uint16(x86_xSetOp), uint16(x86_SETLE),
+ /*5698*/ uint16(x86_xReadSlashR),
+ /*5699*/ uint16(x86_xArgRM8),
+ /*5700*/ uint16(x86_xMatch),
+ /*5701*/ uint16(x86_xSetOp), uint16(x86_SETG),
+ /*5703*/ uint16(x86_xReadSlashR),
+ /*5704*/ uint16(x86_xArgRM8),
+ /*5705*/ uint16(x86_xMatch),
+ /*5706*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*5708*/ uint16(x86_xArgFS),
+ /*5709*/ uint16(x86_xMatch),
+ /*5710*/ uint16(x86_xCondIs64), 5713, 5725,
+ /*5713*/ uint16(x86_xCondDataSize), 5717, 5721, 0,
+ /*5717*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5719*/ uint16(x86_xArgFS),
+ /*5720*/ uint16(x86_xMatch),
+ /*5721*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5723*/ uint16(x86_xArgFS),
+ /*5724*/ uint16(x86_xMatch),
+ /*5725*/ uint16(x86_xCondDataSize), 5717, 5729, 5733,
+ /*5729*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5731*/ uint16(x86_xArgFS),
+ /*5732*/ uint16(x86_xMatch),
+ /*5733*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5735*/ uint16(x86_xArgFS),
+ /*5736*/ uint16(x86_xMatch),
+ /*5737*/ uint16(x86_xSetOp), uint16(x86_CPUID),
+ /*5739*/ uint16(x86_xMatch),
+ /*5740*/ uint16(x86_xCondIs64), 5743, 5759,
+ /*5743*/ uint16(x86_xCondDataSize), 5747, 5753, 0,
+ /*5747*/ uint16(x86_xSetOp), uint16(x86_BT),
+ /*5749*/ uint16(x86_xReadSlashR),
+ /*5750*/ uint16(x86_xArgRM16),
+ /*5751*/ uint16(x86_xArgR16),
+ /*5752*/ uint16(x86_xMatch),
+ /*5753*/ uint16(x86_xSetOp), uint16(x86_BT),
+ /*5755*/ uint16(x86_xReadSlashR),
+ /*5756*/ uint16(x86_xArgRM32),
+ /*5757*/ uint16(x86_xArgR32),
+ /*5758*/ uint16(x86_xMatch),
+ /*5759*/ uint16(x86_xCondDataSize), 5747, 5753, 5763,
+ /*5763*/ uint16(x86_xSetOp), uint16(x86_BT),
+ /*5765*/ uint16(x86_xReadSlashR),
+ /*5766*/ uint16(x86_xArgRM64),
+ /*5767*/ uint16(x86_xArgR64),
+ /*5768*/ uint16(x86_xMatch),
+ /*5769*/ uint16(x86_xCondIs64), 5772, 5792,
+ /*5772*/ uint16(x86_xCondDataSize), 5776, 5784, 0,
+ /*5776*/ uint16(x86_xSetOp), uint16(x86_SHLD),
+ /*5778*/ uint16(x86_xReadSlashR),
+ /*5779*/ uint16(x86_xReadIb),
+ /*5780*/ uint16(x86_xArgRM16),
+ /*5781*/ uint16(x86_xArgR16),
+ /*5782*/ uint16(x86_xArgImm8u),
+ /*5783*/ uint16(x86_xMatch),
+ /*5784*/ uint16(x86_xSetOp), uint16(x86_SHLD),
+ /*5786*/ uint16(x86_xReadSlashR),
+ /*5787*/ uint16(x86_xReadIb),
+ /*5788*/ uint16(x86_xArgRM32),
+ /*5789*/ uint16(x86_xArgR32),
+ /*5790*/ uint16(x86_xArgImm8u),
+ /*5791*/ uint16(x86_xMatch),
+ /*5792*/ uint16(x86_xCondDataSize), 5776, 5784, 5796,
+ /*5796*/ uint16(x86_xSetOp), uint16(x86_SHLD),
+ /*5798*/ uint16(x86_xReadSlashR),
+ /*5799*/ uint16(x86_xReadIb),
+ /*5800*/ uint16(x86_xArgRM64),
+ /*5801*/ uint16(x86_xArgR64),
+ /*5802*/ uint16(x86_xArgImm8u),
+ /*5803*/ uint16(x86_xMatch),
+ /*5804*/ uint16(x86_xCondIs64), 5807, 5825,
+ /*5807*/ uint16(x86_xCondDataSize), 5811, 5818, 0,
+ /*5811*/ uint16(x86_xSetOp), uint16(x86_SHLD),
+ /*5813*/ uint16(x86_xReadSlashR),
+ /*5814*/ uint16(x86_xArgRM16),
+ /*5815*/ uint16(x86_xArgR16),
+ /*5816*/ uint16(x86_xArgCL),
+ /*5817*/ uint16(x86_xMatch),
+ /*5818*/ uint16(x86_xSetOp), uint16(x86_SHLD),
+ /*5820*/ uint16(x86_xReadSlashR),
+ /*5821*/ uint16(x86_xArgRM32),
+ /*5822*/ uint16(x86_xArgR32),
+ /*5823*/ uint16(x86_xArgCL),
+ /*5824*/ uint16(x86_xMatch),
+ /*5825*/ uint16(x86_xCondDataSize), 5811, 5818, 5829,
+ /*5829*/ uint16(x86_xSetOp), uint16(x86_SHLD),
+ /*5831*/ uint16(x86_xReadSlashR),
+ /*5832*/ uint16(x86_xArgRM64),
+ /*5833*/ uint16(x86_xArgR64),
+ /*5834*/ uint16(x86_xArgCL),
+ /*5835*/ uint16(x86_xMatch),
+ /*5836*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*5838*/ uint16(x86_xArgGS),
+ /*5839*/ uint16(x86_xMatch),
+ /*5840*/ uint16(x86_xCondIs64), 5843, 5855,
+ /*5843*/ uint16(x86_xCondDataSize), 5847, 5851, 0,
+ /*5847*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5849*/ uint16(x86_xArgGS),
+ /*5850*/ uint16(x86_xMatch),
+ /*5851*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5853*/ uint16(x86_xArgGS),
+ /*5854*/ uint16(x86_xMatch),
+ /*5855*/ uint16(x86_xCondDataSize), 5847, 5859, 5863,
+ /*5859*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5861*/ uint16(x86_xArgGS),
+ /*5862*/ uint16(x86_xMatch),
+ /*5863*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*5865*/ uint16(x86_xArgGS),
+ /*5866*/ uint16(x86_xMatch),
+ /*5867*/ uint16(x86_xSetOp), uint16(x86_RSM),
+ /*5869*/ uint16(x86_xMatch),
+ /*5870*/ uint16(x86_xCondIs64), 5873, 5889,
+ /*5873*/ uint16(x86_xCondDataSize), 5877, 5883, 0,
+ /*5877*/ uint16(x86_xSetOp), uint16(x86_BTS),
+ /*5879*/ uint16(x86_xReadSlashR),
+ /*5880*/ uint16(x86_xArgRM16),
+ /*5881*/ uint16(x86_xArgR16),
+ /*5882*/ uint16(x86_xMatch),
+ /*5883*/ uint16(x86_xSetOp), uint16(x86_BTS),
+ /*5885*/ uint16(x86_xReadSlashR),
+ /*5886*/ uint16(x86_xArgRM32),
+ /*5887*/ uint16(x86_xArgR32),
+ /*5888*/ uint16(x86_xMatch),
+ /*5889*/ uint16(x86_xCondDataSize), 5877, 5883, 5893,
+ /*5893*/ uint16(x86_xSetOp), uint16(x86_BTS),
+ /*5895*/ uint16(x86_xReadSlashR),
+ /*5896*/ uint16(x86_xArgRM64),
+ /*5897*/ uint16(x86_xArgR64),
+ /*5898*/ uint16(x86_xMatch),
+ /*5899*/ uint16(x86_xCondIs64), 5902, 5922,
+ /*5902*/ uint16(x86_xCondDataSize), 5906, 5914, 0,
+ /*5906*/ uint16(x86_xSetOp), uint16(x86_SHRD),
+ /*5908*/ uint16(x86_xReadSlashR),
+ /*5909*/ uint16(x86_xReadIb),
+ /*5910*/ uint16(x86_xArgRM16),
+ /*5911*/ uint16(x86_xArgR16),
+ /*5912*/ uint16(x86_xArgImm8u),
+ /*5913*/ uint16(x86_xMatch),
+ /*5914*/ uint16(x86_xSetOp), uint16(x86_SHRD),
+ /*5916*/ uint16(x86_xReadSlashR),
+ /*5917*/ uint16(x86_xReadIb),
+ /*5918*/ uint16(x86_xArgRM32),
+ /*5919*/ uint16(x86_xArgR32),
+ /*5920*/ uint16(x86_xArgImm8u),
+ /*5921*/ uint16(x86_xMatch),
+ /*5922*/ uint16(x86_xCondDataSize), 5906, 5914, 5926,
+ /*5926*/ uint16(x86_xSetOp), uint16(x86_SHRD),
+ /*5928*/ uint16(x86_xReadSlashR),
+ /*5929*/ uint16(x86_xReadIb),
+ /*5930*/ uint16(x86_xArgRM64),
+ /*5931*/ uint16(x86_xArgR64),
+ /*5932*/ uint16(x86_xArgImm8u),
+ /*5933*/ uint16(x86_xMatch),
+ /*5934*/ uint16(x86_xCondIs64), 5937, 5955,
+ /*5937*/ uint16(x86_xCondDataSize), 5941, 5948, 0,
+ /*5941*/ uint16(x86_xSetOp), uint16(x86_SHRD),
+ /*5943*/ uint16(x86_xReadSlashR),
+ /*5944*/ uint16(x86_xArgRM16),
+ /*5945*/ uint16(x86_xArgR16),
+ /*5946*/ uint16(x86_xArgCL),
+ /*5947*/ uint16(x86_xMatch),
+ /*5948*/ uint16(x86_xSetOp), uint16(x86_SHRD),
+ /*5950*/ uint16(x86_xReadSlashR),
+ /*5951*/ uint16(x86_xArgRM32),
+ /*5952*/ uint16(x86_xArgR32),
+ /*5953*/ uint16(x86_xArgCL),
+ /*5954*/ uint16(x86_xMatch),
+ /*5955*/ uint16(x86_xCondDataSize), 5941, 5948, 5959,
+ /*5959*/ uint16(x86_xSetOp), uint16(x86_SHRD),
+ /*5961*/ uint16(x86_xReadSlashR),
+ /*5962*/ uint16(x86_xArgRM64),
+ /*5963*/ uint16(x86_xArgR64),
+ /*5964*/ uint16(x86_xArgCL),
+ /*5965*/ uint16(x86_xMatch),
+ /*5966*/ uint16(x86_xCondByte), 3,
+ 0xE8, 6215,
+ 0xF0, 6218,
+ 0xF8, 6221,
+ /*5974*/ uint16(x86_xCondSlashR),
+ 5983, // 0
+ 6037, // 1
+ 6091, // 2
+ 6120, // 3
+ 6149, // 4
+ 6172, // 5
+ 6195, // 6
+ 6211, // 7
+ /*5983*/ uint16(x86_xCondIs64), 5986, 5998,
+ /*5986*/ uint16(x86_xCondDataSize), 5990, 5994, 0,
+ /*5990*/ uint16(x86_xSetOp), uint16(x86_FXSAVE),
+ /*5992*/ uint16(x86_xArgM512byte),
+ /*5993*/ uint16(x86_xMatch),
+ /*5994*/ uint16(x86_xSetOp), uint16(x86_FXSAVE),
+ /*5996*/ uint16(x86_xArgM512byte),
+ /*5997*/ uint16(x86_xMatch),
+ /*5998*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6012,
+ 0x0, 6004,
+ /*6004*/ uint16(x86_xCondDataSize), 5990, 5994, 6008,
+ /*6008*/ uint16(x86_xSetOp), uint16(x86_FXSAVE64),
+ /*6010*/ uint16(x86_xArgM512byte),
+ /*6011*/ uint16(x86_xMatch),
+ /*6012*/ uint16(x86_xCondDataSize), 6016, 6023, 6030,
+ /*6016*/ uint16(x86_xCondIsMem), 6019, 0,
+ /*6019*/ uint16(x86_xSetOp), uint16(x86_RDFSBASE),
+ /*6021*/ uint16(x86_xArgRM32),
+ /*6022*/ uint16(x86_xMatch),
+ /*6023*/ uint16(x86_xCondIsMem), 6026, 0,
+ /*6026*/ uint16(x86_xSetOp), uint16(x86_RDFSBASE),
+ /*6028*/ uint16(x86_xArgRM32),
+ /*6029*/ uint16(x86_xMatch),
+ /*6030*/ uint16(x86_xCondIsMem), 6033, 0,
+ /*6033*/ uint16(x86_xSetOp), uint16(x86_RDFSBASE),
+ /*6035*/ uint16(x86_xArgRM64),
+ /*6036*/ uint16(x86_xMatch),
+ /*6037*/ uint16(x86_xCondIs64), 6040, 6052,
+ /*6040*/ uint16(x86_xCondDataSize), 6044, 6048, 0,
+ /*6044*/ uint16(x86_xSetOp), uint16(x86_FXRSTOR),
+ /*6046*/ uint16(x86_xArgM512byte),
+ /*6047*/ uint16(x86_xMatch),
+ /*6048*/ uint16(x86_xSetOp), uint16(x86_FXRSTOR),
+ /*6050*/ uint16(x86_xArgM512byte),
+ /*6051*/ uint16(x86_xMatch),
+ /*6052*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6066,
+ 0x0, 6058,
+ /*6058*/ uint16(x86_xCondDataSize), 6044, 6048, 6062,
+ /*6062*/ uint16(x86_xSetOp), uint16(x86_FXRSTOR64),
+ /*6064*/ uint16(x86_xArgM512byte),
+ /*6065*/ uint16(x86_xMatch),
+ /*6066*/ uint16(x86_xCondDataSize), 6070, 6077, 6084,
+ /*6070*/ uint16(x86_xCondIsMem), 6073, 0,
+ /*6073*/ uint16(x86_xSetOp), uint16(x86_RDGSBASE),
+ /*6075*/ uint16(x86_xArgRM32),
+ /*6076*/ uint16(x86_xMatch),
+ /*6077*/ uint16(x86_xCondIsMem), 6080, 0,
+ /*6080*/ uint16(x86_xSetOp), uint16(x86_RDGSBASE),
+ /*6082*/ uint16(x86_xArgRM32),
+ /*6083*/ uint16(x86_xMatch),
+ /*6084*/ uint16(x86_xCondIsMem), 6087, 0,
+ /*6087*/ uint16(x86_xSetOp), uint16(x86_RDGSBASE),
+ /*6089*/ uint16(x86_xArgRM64),
+ /*6090*/ uint16(x86_xMatch),
+ /*6091*/ uint16(x86_xCondIs64), 6094, 6098,
+ /*6094*/ uint16(x86_xSetOp), uint16(x86_LDMXCSR),
+ /*6096*/ uint16(x86_xArgM32),
+ /*6097*/ uint16(x86_xMatch),
+ /*6098*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6104,
+ 0x0, 6094,
+ /*6104*/ uint16(x86_xCondDataSize), 6108, 6112, 6116,
+ /*6108*/ uint16(x86_xSetOp), uint16(x86_WRFSBASE),
+ /*6110*/ uint16(x86_xArgRM32),
+ /*6111*/ uint16(x86_xMatch),
+ /*6112*/ uint16(x86_xSetOp), uint16(x86_WRFSBASE),
+ /*6114*/ uint16(x86_xArgRM32),
+ /*6115*/ uint16(x86_xMatch),
+ /*6116*/ uint16(x86_xSetOp), uint16(x86_WRFSBASE),
+ /*6118*/ uint16(x86_xArgRM64),
+ /*6119*/ uint16(x86_xMatch),
+ /*6120*/ uint16(x86_xCondIs64), 6123, 6127,
+ /*6123*/ uint16(x86_xSetOp), uint16(x86_STMXCSR),
+ /*6125*/ uint16(x86_xArgM32),
+ /*6126*/ uint16(x86_xMatch),
+ /*6127*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6133,
+ 0x0, 6123,
+ /*6133*/ uint16(x86_xCondDataSize), 6137, 6141, 6145,
+ /*6137*/ uint16(x86_xSetOp), uint16(x86_WRGSBASE),
+ /*6139*/ uint16(x86_xArgRM32),
+ /*6140*/ uint16(x86_xMatch),
+ /*6141*/ uint16(x86_xSetOp), uint16(x86_WRGSBASE),
+ /*6143*/ uint16(x86_xArgRM32),
+ /*6144*/ uint16(x86_xMatch),
+ /*6145*/ uint16(x86_xSetOp), uint16(x86_WRGSBASE),
+ /*6147*/ uint16(x86_xArgRM64),
+ /*6148*/ uint16(x86_xMatch),
+ /*6149*/ uint16(x86_xCondIs64), 6152, 6164,
+ /*6152*/ uint16(x86_xCondDataSize), 6156, 6160, 0,
+ /*6156*/ uint16(x86_xSetOp), uint16(x86_XSAVE),
+ /*6158*/ uint16(x86_xArgMem),
+ /*6159*/ uint16(x86_xMatch),
+ /*6160*/ uint16(x86_xSetOp), uint16(x86_XSAVE),
+ /*6162*/ uint16(x86_xArgMem),
+ /*6163*/ uint16(x86_xMatch),
+ /*6164*/ uint16(x86_xCondDataSize), 6156, 6160, 6168,
+ /*6168*/ uint16(x86_xSetOp), uint16(x86_XSAVE64),
+ /*6170*/ uint16(x86_xArgMem),
+ /*6171*/ uint16(x86_xMatch),
+ /*6172*/ uint16(x86_xCondIs64), 6175, 6187,
+ /*6175*/ uint16(x86_xCondDataSize), 6179, 6183, 0,
+ /*6179*/ uint16(x86_xSetOp), uint16(x86_XRSTOR),
+ /*6181*/ uint16(x86_xArgMem),
+ /*6182*/ uint16(x86_xMatch),
+ /*6183*/ uint16(x86_xSetOp), uint16(x86_XRSTOR),
+ /*6185*/ uint16(x86_xArgMem),
+ /*6186*/ uint16(x86_xMatch),
+ /*6187*/ uint16(x86_xCondDataSize), 6179, 6183, 6191,
+ /*6191*/ uint16(x86_xSetOp), uint16(x86_XRSTOR64),
+ /*6193*/ uint16(x86_xArgMem),
+ /*6194*/ uint16(x86_xMatch),
+ /*6195*/ uint16(x86_xCondDataSize), 6199, 6203, 6207,
+ /*6199*/ uint16(x86_xSetOp), uint16(x86_XSAVEOPT),
+ /*6201*/ uint16(x86_xArgMem),
+ /*6202*/ uint16(x86_xMatch),
+ /*6203*/ uint16(x86_xSetOp), uint16(x86_XSAVEOPT),
+ /*6205*/ uint16(x86_xArgMem),
+ /*6206*/ uint16(x86_xMatch),
+ /*6207*/ uint16(x86_xSetOp), uint16(x86_XSAVEOPT64),
+ /*6209*/ uint16(x86_xArgMem),
+ /*6210*/ uint16(x86_xMatch),
+ /*6211*/ uint16(x86_xSetOp), uint16(x86_CLFLUSH),
+ /*6213*/ uint16(x86_xArgM8),
+ /*6214*/ uint16(x86_xMatch),
+ /*6215*/ uint16(x86_xSetOp), uint16(x86_LFENCE),
+ /*6217*/ uint16(x86_xMatch),
+ /*6218*/ uint16(x86_xSetOp), uint16(x86_MFENCE),
+ /*6220*/ uint16(x86_xMatch),
+ /*6221*/ uint16(x86_xSetOp), uint16(x86_SFENCE),
+ /*6223*/ uint16(x86_xMatch),
+ /*6224*/ uint16(x86_xCondIs64), 6227, 6243,
+ /*6227*/ uint16(x86_xCondDataSize), 6231, 6237, 0,
+ /*6231*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*6233*/ uint16(x86_xReadSlashR),
+ /*6234*/ uint16(x86_xArgR16),
+ /*6235*/ uint16(x86_xArgRM16),
+ /*6236*/ uint16(x86_xMatch),
+ /*6237*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*6239*/ uint16(x86_xReadSlashR),
+ /*6240*/ uint16(x86_xArgR32),
+ /*6241*/ uint16(x86_xArgRM32),
+ /*6242*/ uint16(x86_xMatch),
+ /*6243*/ uint16(x86_xCondDataSize), 6231, 6237, 6247,
+ /*6247*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*6249*/ uint16(x86_xReadSlashR),
+ /*6250*/ uint16(x86_xArgR64),
+ /*6251*/ uint16(x86_xArgRM64),
+ /*6252*/ uint16(x86_xMatch),
+ /*6253*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
+ /*6255*/ uint16(x86_xReadSlashR),
+ /*6256*/ uint16(x86_xArgRM8),
+ /*6257*/ uint16(x86_xArgR8),
+ /*6258*/ uint16(x86_xMatch),
+ /*6259*/ uint16(x86_xCondIs64), 6262, 6278,
+ /*6262*/ uint16(x86_xCondDataSize), 6266, 6272, 0,
+ /*6266*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
+ /*6268*/ uint16(x86_xReadSlashR),
+ /*6269*/ uint16(x86_xArgRM16),
+ /*6270*/ uint16(x86_xArgR16),
+ /*6271*/ uint16(x86_xMatch),
+ /*6272*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
+ /*6274*/ uint16(x86_xReadSlashR),
+ /*6275*/ uint16(x86_xArgRM32),
+ /*6276*/ uint16(x86_xArgR32),
+ /*6277*/ uint16(x86_xMatch),
+ /*6278*/ uint16(x86_xCondDataSize), 6266, 6272, 6282,
+ /*6282*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
+ /*6284*/ uint16(x86_xReadSlashR),
+ /*6285*/ uint16(x86_xArgRM64),
+ /*6286*/ uint16(x86_xArgR64),
+ /*6287*/ uint16(x86_xMatch),
+ /*6288*/ uint16(x86_xCondIs64), 6291, 6307,
+ /*6291*/ uint16(x86_xCondDataSize), 6295, 6301, 0,
+ /*6295*/ uint16(x86_xSetOp), uint16(x86_LSS),
+ /*6297*/ uint16(x86_xReadSlashR),
+ /*6298*/ uint16(x86_xArgR16),
+ /*6299*/ uint16(x86_xArgM16colon16),
+ /*6300*/ uint16(x86_xMatch),
+ /*6301*/ uint16(x86_xSetOp), uint16(x86_LSS),
+ /*6303*/ uint16(x86_xReadSlashR),
+ /*6304*/ uint16(x86_xArgR32),
+ /*6305*/ uint16(x86_xArgM16colon32),
+ /*6306*/ uint16(x86_xMatch),
+ /*6307*/ uint16(x86_xCondDataSize), 6295, 6301, 6311,
+ /*6311*/ uint16(x86_xSetOp), uint16(x86_LSS),
+ /*6313*/ uint16(x86_xReadSlashR),
+ /*6314*/ uint16(x86_xArgR64),
+ /*6315*/ uint16(x86_xArgM16colon64),
+ /*6316*/ uint16(x86_xMatch),
+ /*6317*/ uint16(x86_xCondIs64), 6320, 6336,
+ /*6320*/ uint16(x86_xCondDataSize), 6324, 6330, 0,
+ /*6324*/ uint16(x86_xSetOp), uint16(x86_BTR),
+ /*6326*/ uint16(x86_xReadSlashR),
+ /*6327*/ uint16(x86_xArgRM16),
+ /*6328*/ uint16(x86_xArgR16),
+ /*6329*/ uint16(x86_xMatch),
+ /*6330*/ uint16(x86_xSetOp), uint16(x86_BTR),
+ /*6332*/ uint16(x86_xReadSlashR),
+ /*6333*/ uint16(x86_xArgRM32),
+ /*6334*/ uint16(x86_xArgR32),
+ /*6335*/ uint16(x86_xMatch),
+ /*6336*/ uint16(x86_xCondDataSize), 6324, 6330, 6340,
+ /*6340*/ uint16(x86_xSetOp), uint16(x86_BTR),
+ /*6342*/ uint16(x86_xReadSlashR),
+ /*6343*/ uint16(x86_xArgRM64),
+ /*6344*/ uint16(x86_xArgR64),
+ /*6345*/ uint16(x86_xMatch),
+ /*6346*/ uint16(x86_xCondIs64), 6349, 6365,
+ /*6349*/ uint16(x86_xCondDataSize), 6353, 6359, 0,
+ /*6353*/ uint16(x86_xSetOp), uint16(x86_LFS),
+ /*6355*/ uint16(x86_xReadSlashR),
+ /*6356*/ uint16(x86_xArgR16),
+ /*6357*/ uint16(x86_xArgM16colon16),
+ /*6358*/ uint16(x86_xMatch),
+ /*6359*/ uint16(x86_xSetOp), uint16(x86_LFS),
+ /*6361*/ uint16(x86_xReadSlashR),
+ /*6362*/ uint16(x86_xArgR32),
+ /*6363*/ uint16(x86_xArgM16colon32),
+ /*6364*/ uint16(x86_xMatch),
+ /*6365*/ uint16(x86_xCondDataSize), 6353, 6359, 6369,
+ /*6369*/ uint16(x86_xSetOp), uint16(x86_LFS),
+ /*6371*/ uint16(x86_xReadSlashR),
+ /*6372*/ uint16(x86_xArgR64),
+ /*6373*/ uint16(x86_xArgM16colon64),
+ /*6374*/ uint16(x86_xMatch),
+ /*6375*/ uint16(x86_xCondIs64), 6378, 6394,
+ /*6378*/ uint16(x86_xCondDataSize), 6382, 6388, 0,
+ /*6382*/ uint16(x86_xSetOp), uint16(x86_LGS),
+ /*6384*/ uint16(x86_xReadSlashR),
+ /*6385*/ uint16(x86_xArgR16),
+ /*6386*/ uint16(x86_xArgM16colon16),
+ /*6387*/ uint16(x86_xMatch),
+ /*6388*/ uint16(x86_xSetOp), uint16(x86_LGS),
+ /*6390*/ uint16(x86_xReadSlashR),
+ /*6391*/ uint16(x86_xArgR32),
+ /*6392*/ uint16(x86_xArgM16colon32),
+ /*6393*/ uint16(x86_xMatch),
+ /*6394*/ uint16(x86_xCondDataSize), 6382, 6388, 6398,
+ /*6398*/ uint16(x86_xSetOp), uint16(x86_LGS),
+ /*6400*/ uint16(x86_xReadSlashR),
+ /*6401*/ uint16(x86_xArgR64),
+ /*6402*/ uint16(x86_xArgM16colon64),
+ /*6403*/ uint16(x86_xMatch),
+ /*6404*/ uint16(x86_xCondIs64), 6407, 6423,
+ /*6407*/ uint16(x86_xCondDataSize), 6411, 6417, 0,
+ /*6411*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
+ /*6413*/ uint16(x86_xReadSlashR),
+ /*6414*/ uint16(x86_xArgR16),
+ /*6415*/ uint16(x86_xArgRM8),
+ /*6416*/ uint16(x86_xMatch),
+ /*6417*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
+ /*6419*/ uint16(x86_xReadSlashR),
+ /*6420*/ uint16(x86_xArgR32),
+ /*6421*/ uint16(x86_xArgRM8),
+ /*6422*/ uint16(x86_xMatch),
+ /*6423*/ uint16(x86_xCondDataSize), 6411, 6417, 6427,
+ /*6427*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
+ /*6429*/ uint16(x86_xReadSlashR),
+ /*6430*/ uint16(x86_xArgR64),
+ /*6431*/ uint16(x86_xArgRM8),
+ /*6432*/ uint16(x86_xMatch),
+ /*6433*/ uint16(x86_xCondIs64), 6436, 6452,
+ /*6436*/ uint16(x86_xCondDataSize), 6440, 6446, 0,
+ /*6440*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
+ /*6442*/ uint16(x86_xReadSlashR),
+ /*6443*/ uint16(x86_xArgR16),
+ /*6444*/ uint16(x86_xArgRM16),
+ /*6445*/ uint16(x86_xMatch),
+ /*6446*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
+ /*6448*/ uint16(x86_xReadSlashR),
+ /*6449*/ uint16(x86_xArgR32),
+ /*6450*/ uint16(x86_xArgRM16),
+ /*6451*/ uint16(x86_xMatch),
+ /*6452*/ uint16(x86_xCondDataSize), 6440, 6446, 6456,
+ /*6456*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
+ /*6458*/ uint16(x86_xReadSlashR),
+ /*6459*/ uint16(x86_xArgR64),
+ /*6460*/ uint16(x86_xArgRM16),
+ /*6461*/ uint16(x86_xMatch),
+ /*6462*/ uint16(x86_xCondIs64), 6465, 6485,
+ /*6465*/ uint16(x86_xCondPrefix), 1,
+ 0xF3, 6469,
+ /*6469*/ uint16(x86_xCondDataSize), 6473, 6479, 0,
+ /*6473*/ uint16(x86_xSetOp), uint16(x86_POPCNT),
+ /*6475*/ uint16(x86_xReadSlashR),
+ /*6476*/ uint16(x86_xArgR16),
+ /*6477*/ uint16(x86_xArgRM16),
+ /*6478*/ uint16(x86_xMatch),
+ /*6479*/ uint16(x86_xSetOp), uint16(x86_POPCNT),
+ /*6481*/ uint16(x86_xReadSlashR),
+ /*6482*/ uint16(x86_xArgR32),
+ /*6483*/ uint16(x86_xArgRM32),
+ /*6484*/ uint16(x86_xMatch),
+ /*6485*/ uint16(x86_xCondPrefix), 1,
+ 0xF3, 6489,
+ /*6489*/ uint16(x86_xCondDataSize), 6473, 6479, 6493,
+ /*6493*/ uint16(x86_xSetOp), uint16(x86_POPCNT),
+ /*6495*/ uint16(x86_xReadSlashR),
+ /*6496*/ uint16(x86_xArgR64),
+ /*6497*/ uint16(x86_xArgRM64),
+ /*6498*/ uint16(x86_xMatch),
+ /*6499*/ uint16(x86_xSetOp), uint16(x86_UD1),
+ /*6501*/ uint16(x86_xMatch),
+ /*6502*/ uint16(x86_xCondSlashR),
+ 0, // 0
+ 0, // 1
+ 0, // 2
+ 0, // 3
+ 6511, // 4
+ 6540, // 5
+ 6569, // 6
+ 6598, // 7
+ /*6511*/ uint16(x86_xCondIs64), 6514, 6530,
+ /*6514*/ uint16(x86_xCondDataSize), 6518, 6524, 0,
+ /*6518*/ uint16(x86_xSetOp), uint16(x86_BT),
+ /*6520*/ uint16(x86_xReadIb),
+ /*6521*/ uint16(x86_xArgRM16),
+ /*6522*/ uint16(x86_xArgImm8u),
+ /*6523*/ uint16(x86_xMatch),
+ /*6524*/ uint16(x86_xSetOp), uint16(x86_BT),
+ /*6526*/ uint16(x86_xReadIb),
+ /*6527*/ uint16(x86_xArgRM32),
+ /*6528*/ uint16(x86_xArgImm8u),
+ /*6529*/ uint16(x86_xMatch),
+ /*6530*/ uint16(x86_xCondDataSize), 6518, 6524, 6534,
+ /*6534*/ uint16(x86_xSetOp), uint16(x86_BT),
+ /*6536*/ uint16(x86_xReadIb),
+ /*6537*/ uint16(x86_xArgRM64),
+ /*6538*/ uint16(x86_xArgImm8u),
+ /*6539*/ uint16(x86_xMatch),
+ /*6540*/ uint16(x86_xCondIs64), 6543, 6559,
+ /*6543*/ uint16(x86_xCondDataSize), 6547, 6553, 0,
+ /*6547*/ uint16(x86_xSetOp), uint16(x86_BTS),
+ /*6549*/ uint16(x86_xReadIb),
+ /*6550*/ uint16(x86_xArgRM16),
+ /*6551*/ uint16(x86_xArgImm8u),
+ /*6552*/ uint16(x86_xMatch),
+ /*6553*/ uint16(x86_xSetOp), uint16(x86_BTS),
+ /*6555*/ uint16(x86_xReadIb),
+ /*6556*/ uint16(x86_xArgRM32),
+ /*6557*/ uint16(x86_xArgImm8u),
+ /*6558*/ uint16(x86_xMatch),
+ /*6559*/ uint16(x86_xCondDataSize), 6547, 6553, 6563,
+ /*6563*/ uint16(x86_xSetOp), uint16(x86_BTS),
+ /*6565*/ uint16(x86_xReadIb),
+ /*6566*/ uint16(x86_xArgRM64),
+ /*6567*/ uint16(x86_xArgImm8u),
+ /*6568*/ uint16(x86_xMatch),
+ /*6569*/ uint16(x86_xCondIs64), 6572, 6588,
+ /*6572*/ uint16(x86_xCondDataSize), 6576, 6582, 0,
+ /*6576*/ uint16(x86_xSetOp), uint16(x86_BTR),
+ /*6578*/ uint16(x86_xReadIb),
+ /*6579*/ uint16(x86_xArgRM16),
+ /*6580*/ uint16(x86_xArgImm8u),
+ /*6581*/ uint16(x86_xMatch),
+ /*6582*/ uint16(x86_xSetOp), uint16(x86_BTR),
+ /*6584*/ uint16(x86_xReadIb),
+ /*6585*/ uint16(x86_xArgRM32),
+ /*6586*/ uint16(x86_xArgImm8u),
+ /*6587*/ uint16(x86_xMatch),
+ /*6588*/ uint16(x86_xCondDataSize), 6576, 6582, 6592,
+ /*6592*/ uint16(x86_xSetOp), uint16(x86_BTR),
+ /*6594*/ uint16(x86_xReadIb),
+ /*6595*/ uint16(x86_xArgRM64),
+ /*6596*/ uint16(x86_xArgImm8u),
+ /*6597*/ uint16(x86_xMatch),
+ /*6598*/ uint16(x86_xCondIs64), 6601, 6617,
+ /*6601*/ uint16(x86_xCondDataSize), 6605, 6611, 0,
+ /*6605*/ uint16(x86_xSetOp), uint16(x86_BTC),
+ /*6607*/ uint16(x86_xReadIb),
+ /*6608*/ uint16(x86_xArgRM16),
+ /*6609*/ uint16(x86_xArgImm8u),
+ /*6610*/ uint16(x86_xMatch),
+ /*6611*/ uint16(x86_xSetOp), uint16(x86_BTC),
+ /*6613*/ uint16(x86_xReadIb),
+ /*6614*/ uint16(x86_xArgRM32),
+ /*6615*/ uint16(x86_xArgImm8u),
+ /*6616*/ uint16(x86_xMatch),
+ /*6617*/ uint16(x86_xCondDataSize), 6605, 6611, 6621,
+ /*6621*/ uint16(x86_xSetOp), uint16(x86_BTC),
+ /*6623*/ uint16(x86_xReadIb),
+ /*6624*/ uint16(x86_xArgRM64),
+ /*6625*/ uint16(x86_xArgImm8u),
+ /*6626*/ uint16(x86_xMatch),
+ /*6627*/ uint16(x86_xCondIs64), 6630, 6646,
+ /*6630*/ uint16(x86_xCondDataSize), 6634, 6640, 0,
+ /*6634*/ uint16(x86_xSetOp), uint16(x86_BTC),
+ /*6636*/ uint16(x86_xReadSlashR),
+ /*6637*/ uint16(x86_xArgRM16),
+ /*6638*/ uint16(x86_xArgR16),
+ /*6639*/ uint16(x86_xMatch),
+ /*6640*/ uint16(x86_xSetOp), uint16(x86_BTC),
+ /*6642*/ uint16(x86_xReadSlashR),
+ /*6643*/ uint16(x86_xArgRM32),
+ /*6644*/ uint16(x86_xArgR32),
+ /*6645*/ uint16(x86_xMatch),
+ /*6646*/ uint16(x86_xCondDataSize), 6634, 6640, 6650,
+ /*6650*/ uint16(x86_xSetOp), uint16(x86_BTC),
+ /*6652*/ uint16(x86_xReadSlashR),
+ /*6653*/ uint16(x86_xArgRM64),
+ /*6654*/ uint16(x86_xArgR64),
+ /*6655*/ uint16(x86_xMatch),
+ /*6656*/ uint16(x86_xCondIs64), 6659, 6697,
+ /*6659*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6681,
+ 0x0, 6665,
+ /*6665*/ uint16(x86_xCondDataSize), 6669, 6675, 0,
+ /*6669*/ uint16(x86_xSetOp), uint16(x86_BSF),
+ /*6671*/ uint16(x86_xReadSlashR),
+ /*6672*/ uint16(x86_xArgR16),
+ /*6673*/ uint16(x86_xArgRM16),
+ /*6674*/ uint16(x86_xMatch),
+ /*6675*/ uint16(x86_xSetOp), uint16(x86_BSF),
+ /*6677*/ uint16(x86_xReadSlashR),
+ /*6678*/ uint16(x86_xArgR32),
+ /*6679*/ uint16(x86_xArgRM32),
+ /*6680*/ uint16(x86_xMatch),
+ /*6681*/ uint16(x86_xCondDataSize), 6685, 6691, 0,
+ /*6685*/ uint16(x86_xSetOp), uint16(x86_TZCNT),
+ /*6687*/ uint16(x86_xReadSlashR),
+ /*6688*/ uint16(x86_xArgR16),
+ /*6689*/ uint16(x86_xArgRM16),
+ /*6690*/ uint16(x86_xMatch),
+ /*6691*/ uint16(x86_xSetOp), uint16(x86_TZCNT),
+ /*6693*/ uint16(x86_xReadSlashR),
+ /*6694*/ uint16(x86_xArgR32),
+ /*6695*/ uint16(x86_xArgRM32),
+ /*6696*/ uint16(x86_xMatch),
+ /*6697*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6713,
+ 0x0, 6703,
+ /*6703*/ uint16(x86_xCondDataSize), 6669, 6675, 6707,
+ /*6707*/ uint16(x86_xSetOp), uint16(x86_BSF),
+ /*6709*/ uint16(x86_xReadSlashR),
+ /*6710*/ uint16(x86_xArgR64),
+ /*6711*/ uint16(x86_xArgRM64),
+ /*6712*/ uint16(x86_xMatch),
+ /*6713*/ uint16(x86_xCondDataSize), 6685, 6691, 6717,
+ /*6717*/ uint16(x86_xSetOp), uint16(x86_TZCNT),
+ /*6719*/ uint16(x86_xReadSlashR),
+ /*6720*/ uint16(x86_xArgR64),
+ /*6721*/ uint16(x86_xArgRM64),
+ /*6722*/ uint16(x86_xMatch),
+ /*6723*/ uint16(x86_xCondIs64), 6726, 6764,
+ /*6726*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6748,
+ 0x0, 6732,
+ /*6732*/ uint16(x86_xCondDataSize), 6736, 6742, 0,
+ /*6736*/ uint16(x86_xSetOp), uint16(x86_BSR),
+ /*6738*/ uint16(x86_xReadSlashR),
+ /*6739*/ uint16(x86_xArgR16),
+ /*6740*/ uint16(x86_xArgRM16),
+ /*6741*/ uint16(x86_xMatch),
+ /*6742*/ uint16(x86_xSetOp), uint16(x86_BSR),
+ /*6744*/ uint16(x86_xReadSlashR),
+ /*6745*/ uint16(x86_xArgR32),
+ /*6746*/ uint16(x86_xArgRM32),
+ /*6747*/ uint16(x86_xMatch),
+ /*6748*/ uint16(x86_xCondDataSize), 6752, 6758, 0,
+ /*6752*/ uint16(x86_xSetOp), uint16(x86_LZCNT),
+ /*6754*/ uint16(x86_xReadSlashR),
+ /*6755*/ uint16(x86_xArgR16),
+ /*6756*/ uint16(x86_xArgRM16),
+ /*6757*/ uint16(x86_xMatch),
+ /*6758*/ uint16(x86_xSetOp), uint16(x86_LZCNT),
+ /*6760*/ uint16(x86_xReadSlashR),
+ /*6761*/ uint16(x86_xArgR32),
+ /*6762*/ uint16(x86_xArgRM32),
+ /*6763*/ uint16(x86_xMatch),
+ /*6764*/ uint16(x86_xCondPrefix), 2,
+ 0xF3, 6780,
+ 0x0, 6770,
+ /*6770*/ uint16(x86_xCondDataSize), 6736, 6742, 6774,
+ /*6774*/ uint16(x86_xSetOp), uint16(x86_BSR),
+ /*6776*/ uint16(x86_xReadSlashR),
+ /*6777*/ uint16(x86_xArgR64),
+ /*6778*/ uint16(x86_xArgRM64),
+ /*6779*/ uint16(x86_xMatch),
+ /*6780*/ uint16(x86_xCondDataSize), 6752, 6758, 6784,
+ /*6784*/ uint16(x86_xSetOp), uint16(x86_LZCNT),
+ /*6786*/ uint16(x86_xReadSlashR),
+ /*6787*/ uint16(x86_xArgR64),
+ /*6788*/ uint16(x86_xArgRM64),
+ /*6789*/ uint16(x86_xMatch),
+ /*6790*/ uint16(x86_xCondIs64), 6793, 6809,
+ /*6793*/ uint16(x86_xCondDataSize), 6797, 6803, 0,
+ /*6797*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
+ /*6799*/ uint16(x86_xReadSlashR),
+ /*6800*/ uint16(x86_xArgR16),
+ /*6801*/ uint16(x86_xArgRM8),
+ /*6802*/ uint16(x86_xMatch),
+ /*6803*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
+ /*6805*/ uint16(x86_xReadSlashR),
+ /*6806*/ uint16(x86_xArgR32),
+ /*6807*/ uint16(x86_xArgRM8),
+ /*6808*/ uint16(x86_xMatch),
+ /*6809*/ uint16(x86_xCondDataSize), 6797, 6803, 6813,
+ /*6813*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
+ /*6815*/ uint16(x86_xReadSlashR),
+ /*6816*/ uint16(x86_xArgR64),
+ /*6817*/ uint16(x86_xArgRM8),
+ /*6818*/ uint16(x86_xMatch),
+ /*6819*/ uint16(x86_xCondIs64), 6822, 6838,
+ /*6822*/ uint16(x86_xCondDataSize), 6826, 6832, 0,
+ /*6826*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
+ /*6828*/ uint16(x86_xReadSlashR),
+ /*6829*/ uint16(x86_xArgR16),
+ /*6830*/ uint16(x86_xArgRM16),
+ /*6831*/ uint16(x86_xMatch),
+ /*6832*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
+ /*6834*/ uint16(x86_xReadSlashR),
+ /*6835*/ uint16(x86_xArgR32),
+ /*6836*/ uint16(x86_xArgRM16),
+ /*6837*/ uint16(x86_xMatch),
+ /*6838*/ uint16(x86_xCondDataSize), 6826, 6832, 6842,
+ /*6842*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
+ /*6844*/ uint16(x86_xReadSlashR),
+ /*6845*/ uint16(x86_xArgR64),
+ /*6846*/ uint16(x86_xArgRM16),
+ /*6847*/ uint16(x86_xMatch),
+ /*6848*/ uint16(x86_xSetOp), uint16(x86_XADD),
+ /*6850*/ uint16(x86_xReadSlashR),
+ /*6851*/ uint16(x86_xArgRM8),
+ /*6852*/ uint16(x86_xArgR8),
+ /*6853*/ uint16(x86_xMatch),
+ /*6854*/ uint16(x86_xCondIs64), 6857, 6873,
+ /*6857*/ uint16(x86_xCondDataSize), 6861, 6867, 0,
+ /*6861*/ uint16(x86_xSetOp), uint16(x86_XADD),
+ /*6863*/ uint16(x86_xReadSlashR),
+ /*6864*/ uint16(x86_xArgRM16),
+ /*6865*/ uint16(x86_xArgR16),
+ /*6866*/ uint16(x86_xMatch),
+ /*6867*/ uint16(x86_xSetOp), uint16(x86_XADD),
+ /*6869*/ uint16(x86_xReadSlashR),
+ /*6870*/ uint16(x86_xArgRM32),
+ /*6871*/ uint16(x86_xArgR32),
+ /*6872*/ uint16(x86_xMatch),
+ /*6873*/ uint16(x86_xCondDataSize), 6861, 6867, 6877,
+ /*6877*/ uint16(x86_xSetOp), uint16(x86_XADD),
+ /*6879*/ uint16(x86_xReadSlashR),
+ /*6880*/ uint16(x86_xArgRM64),
+ /*6881*/ uint16(x86_xArgR64),
+ /*6882*/ uint16(x86_xMatch),
+ /*6883*/ uint16(x86_xCondPrefix), 4,
+ 0xF3, 6917,
+ 0xF2, 6909,
+ 0x66, 6901,
+ 0x0, 6893,
+ /*6893*/ uint16(x86_xSetOp), uint16(x86_CMPPS),
+ /*6895*/ uint16(x86_xReadSlashR),
+ /*6896*/ uint16(x86_xReadIb),
+ /*6897*/ uint16(x86_xArgXmm1),
+ /*6898*/ uint16(x86_xArgXmm2M128),
+ /*6899*/ uint16(x86_xArgImm8u),
+ /*6900*/ uint16(x86_xMatch),
+ /*6901*/ uint16(x86_xSetOp), uint16(x86_CMPPD),
+ /*6903*/ uint16(x86_xReadSlashR),
+ /*6904*/ uint16(x86_xReadIb),
+ /*6905*/ uint16(x86_xArgXmm1),
+ /*6906*/ uint16(x86_xArgXmm2M128),
+ /*6907*/ uint16(x86_xArgImm8u),
+ /*6908*/ uint16(x86_xMatch),
+ /*6909*/ uint16(x86_xSetOp), uint16(x86_CMPSD_XMM),
+ /*6911*/ uint16(x86_xReadSlashR),
+ /*6912*/ uint16(x86_xReadIb),
+ /*6913*/ uint16(x86_xArgXmm1),
+ /*6914*/ uint16(x86_xArgXmm2M64),
+ /*6915*/ uint16(x86_xArgImm8u),
+ /*6916*/ uint16(x86_xMatch),
+ /*6917*/ uint16(x86_xSetOp), uint16(x86_CMPSS),
+ /*6919*/ uint16(x86_xReadSlashR),
+ /*6920*/ uint16(x86_xReadIb),
+ /*6921*/ uint16(x86_xArgXmm1),
+ /*6922*/ uint16(x86_xArgXmm2M32),
+ /*6923*/ uint16(x86_xArgImm8u),
+ /*6924*/ uint16(x86_xMatch),
+ /*6925*/ uint16(x86_xCondIs64), 6928, 6944,
+ /*6928*/ uint16(x86_xCondDataSize), 6932, 6938, 0,
+ /*6932*/ uint16(x86_xSetOp), uint16(x86_MOVNTI),
+ /*6934*/ uint16(x86_xReadSlashR),
+ /*6935*/ uint16(x86_xArgM32),
+ /*6936*/ uint16(x86_xArgR32),
+ /*6937*/ uint16(x86_xMatch),
+ /*6938*/ uint16(x86_xSetOp), uint16(x86_MOVNTI),
+ /*6940*/ uint16(x86_xReadSlashR),
+ /*6941*/ uint16(x86_xArgM32),
+ /*6942*/ uint16(x86_xArgR32),
+ /*6943*/ uint16(x86_xMatch),
+ /*6944*/ uint16(x86_xCondDataSize), 6932, 6938, 6948,
+ /*6948*/ uint16(x86_xSetOp), uint16(x86_MOVNTI),
+ /*6950*/ uint16(x86_xReadSlashR),
+ /*6951*/ uint16(x86_xArgM64),
+ /*6952*/ uint16(x86_xArgR64),
+ /*6953*/ uint16(x86_xMatch),
+ /*6954*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 6968,
+ 0x0, 6960,
+ /*6960*/ uint16(x86_xSetOp), uint16(x86_PINSRW),
+ /*6962*/ uint16(x86_xReadSlashR),
+ /*6963*/ uint16(x86_xReadIb),
+ /*6964*/ uint16(x86_xArgMm),
+ /*6965*/ uint16(x86_xArgR32M16),
+ /*6966*/ uint16(x86_xArgImm8u),
+ /*6967*/ uint16(x86_xMatch),
+ /*6968*/ uint16(x86_xSetOp), uint16(x86_PINSRW),
+ /*6970*/ uint16(x86_xReadSlashR),
+ /*6971*/ uint16(x86_xReadIb),
+ /*6972*/ uint16(x86_xArgXmm),
+ /*6973*/ uint16(x86_xArgR32M16),
+ /*6974*/ uint16(x86_xArgImm8u),
+ /*6975*/ uint16(x86_xMatch),
+ /*6976*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 6990,
+ 0x0, 6982,
+ /*6982*/ uint16(x86_xSetOp), uint16(x86_PEXTRW),
+ /*6984*/ uint16(x86_xReadSlashR),
+ /*6985*/ uint16(x86_xReadIb),
+ /*6986*/ uint16(x86_xArgR32),
+ /*6987*/ uint16(x86_xArgMm2),
+ /*6988*/ uint16(x86_xArgImm8u),
+ /*6989*/ uint16(x86_xMatch),
+ /*6990*/ uint16(x86_xSetOp), uint16(x86_PEXTRW),
+ /*6992*/ uint16(x86_xReadSlashR),
+ /*6993*/ uint16(x86_xReadIb),
+ /*6994*/ uint16(x86_xArgR32),
+ /*6995*/ uint16(x86_xArgXmm2),
+ /*6996*/ uint16(x86_xArgImm8u),
+ /*6997*/ uint16(x86_xMatch),
+ /*6998*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7012,
+ 0x0, 7004,
+ /*7004*/ uint16(x86_xSetOp), uint16(x86_SHUFPS),
+ /*7006*/ uint16(x86_xReadSlashR),
+ /*7007*/ uint16(x86_xReadIb),
+ /*7008*/ uint16(x86_xArgXmm1),
+ /*7009*/ uint16(x86_xArgXmm2M128),
+ /*7010*/ uint16(x86_xArgImm8u),
+ /*7011*/ uint16(x86_xMatch),
+ /*7012*/ uint16(x86_xSetOp), uint16(x86_SHUFPD),
+ /*7014*/ uint16(x86_xReadSlashR),
+ /*7015*/ uint16(x86_xReadIb),
+ /*7016*/ uint16(x86_xArgXmm1),
+ /*7017*/ uint16(x86_xArgXmm2M128),
+ /*7018*/ uint16(x86_xArgImm8u),
+ /*7019*/ uint16(x86_xMatch),
+ /*7020*/ uint16(x86_xCondSlashR),
+ 0, // 0
+ 7029, // 1
+ 0, // 2
+ 7052, // 3
+ 7075, // 4
+ 7098, // 5
+ 7121, // 6
+ 0, // 7
+ /*7029*/ uint16(x86_xCondIs64), 7032, 7044,
+ /*7032*/ uint16(x86_xCondDataSize), 7036, 7040, 0,
+ /*7036*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG8B),
+ /*7038*/ uint16(x86_xArgM64),
+ /*7039*/ uint16(x86_xMatch),
+ /*7040*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG8B),
+ /*7042*/ uint16(x86_xArgM64),
+ /*7043*/ uint16(x86_xMatch),
+ /*7044*/ uint16(x86_xCondDataSize), 7036, 7040, 7048,
+ /*7048*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG16B),
+ /*7050*/ uint16(x86_xArgM128),
+ /*7051*/ uint16(x86_xMatch),
+ /*7052*/ uint16(x86_xCondIs64), 7055, 7067,
+ /*7055*/ uint16(x86_xCondDataSize), 7059, 7063, 0,
+ /*7059*/ uint16(x86_xSetOp), uint16(x86_XRSTORS),
+ /*7061*/ uint16(x86_xArgMem),
+ /*7062*/ uint16(x86_xMatch),
+ /*7063*/ uint16(x86_xSetOp), uint16(x86_XRSTORS),
+ /*7065*/ uint16(x86_xArgMem),
+ /*7066*/ uint16(x86_xMatch),
+ /*7067*/ uint16(x86_xCondDataSize), 7059, 7063, 7071,
+ /*7071*/ uint16(x86_xSetOp), uint16(x86_XRSTORS64),
+ /*7073*/ uint16(x86_xArgMem),
+ /*7074*/ uint16(x86_xMatch),
+ /*7075*/ uint16(x86_xCondIs64), 7078, 7090,
+ /*7078*/ uint16(x86_xCondDataSize), 7082, 7086, 0,
+ /*7082*/ uint16(x86_xSetOp), uint16(x86_XSAVEC),
+ /*7084*/ uint16(x86_xArgMem),
+ /*7085*/ uint16(x86_xMatch),
+ /*7086*/ uint16(x86_xSetOp), uint16(x86_XSAVEC),
+ /*7088*/ uint16(x86_xArgMem),
+ /*7089*/ uint16(x86_xMatch),
+ /*7090*/ uint16(x86_xCondDataSize), 7082, 7086, 7094,
+ /*7094*/ uint16(x86_xSetOp), uint16(x86_XSAVEC64),
+ /*7096*/ uint16(x86_xArgMem),
+ /*7097*/ uint16(x86_xMatch),
+ /*7098*/ uint16(x86_xCondIs64), 7101, 7113,
+ /*7101*/ uint16(x86_xCondDataSize), 7105, 7109, 0,
+ /*7105*/ uint16(x86_xSetOp), uint16(x86_XSAVES),
+ /*7107*/ uint16(x86_xArgMem),
+ /*7108*/ uint16(x86_xMatch),
+ /*7109*/ uint16(x86_xSetOp), uint16(x86_XSAVES),
+ /*7111*/ uint16(x86_xArgMem),
+ /*7112*/ uint16(x86_xMatch),
+ /*7113*/ uint16(x86_xCondDataSize), 7105, 7109, 7117,
+ /*7117*/ uint16(x86_xSetOp), uint16(x86_XSAVES64),
+ /*7119*/ uint16(x86_xArgMem),
+ /*7120*/ uint16(x86_xMatch),
+ /*7121*/ uint16(x86_xCondIs64), 7124, 7142,
+ /*7124*/ uint16(x86_xCondDataSize), 7128, 7135, 0,
+ /*7128*/ uint16(x86_xCondIsMem), 7131, 0,
+ /*7131*/ uint16(x86_xSetOp), uint16(x86_RDRAND),
+ /*7133*/ uint16(x86_xArgRmf16),
+ /*7134*/ uint16(x86_xMatch),
+ /*7135*/ uint16(x86_xCondIsMem), 7138, 0,
+ /*7138*/ uint16(x86_xSetOp), uint16(x86_RDRAND),
+ /*7140*/ uint16(x86_xArgRmf32),
+ /*7141*/ uint16(x86_xMatch),
+ /*7142*/ uint16(x86_xCondDataSize), 7128, 7135, 7146,
+ /*7146*/ uint16(x86_xSetOp), uint16(x86_RDRAND),
+ /*7148*/ uint16(x86_xMatch),
+ /*7149*/ uint16(x86_xCondIs64), 7152, 7164,
+ /*7152*/ uint16(x86_xCondDataSize), 7156, 7160, 0,
+ /*7156*/ uint16(x86_xSetOp), uint16(x86_BSWAP),
+ /*7158*/ uint16(x86_xArgR16op),
+ /*7159*/ uint16(x86_xMatch),
+ /*7160*/ uint16(x86_xSetOp), uint16(x86_BSWAP),
+ /*7162*/ uint16(x86_xArgR32op),
+ /*7163*/ uint16(x86_xMatch),
+ /*7164*/ uint16(x86_xCondDataSize), 7156, 7160, 7168,
+ /*7168*/ uint16(x86_xSetOp), uint16(x86_BSWAP),
+ /*7170*/ uint16(x86_xArgR64op),
+ /*7171*/ uint16(x86_xMatch),
+ /*7172*/ uint16(x86_xCondPrefix), 2,
+ 0xF2, 7184,
+ 0x66, 7178,
+ /*7178*/ uint16(x86_xSetOp), uint16(x86_ADDSUBPD),
+ /*7180*/ uint16(x86_xReadSlashR),
+ /*7181*/ uint16(x86_xArgXmm1),
+ /*7182*/ uint16(x86_xArgXmm2M128),
+ /*7183*/ uint16(x86_xMatch),
+ /*7184*/ uint16(x86_xSetOp), uint16(x86_ADDSUBPS),
+ /*7186*/ uint16(x86_xReadSlashR),
+ /*7187*/ uint16(x86_xArgXmm1),
+ /*7188*/ uint16(x86_xArgXmm2M128),
+ /*7189*/ uint16(x86_xMatch),
+ /*7190*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7202,
+ 0x0, 7196,
+ /*7196*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
+ /*7198*/ uint16(x86_xReadSlashR),
+ /*7199*/ uint16(x86_xArgMm),
+ /*7200*/ uint16(x86_xArgMmM64),
+ /*7201*/ uint16(x86_xMatch),
+ /*7202*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
+ /*7204*/ uint16(x86_xReadSlashR),
+ /*7205*/ uint16(x86_xArgXmm1),
+ /*7206*/ uint16(x86_xArgXmm2M128),
+ /*7207*/ uint16(x86_xMatch),
+ /*7208*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7220,
+ 0x0, 7214,
+ /*7214*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
+ /*7216*/ uint16(x86_xReadSlashR),
+ /*7217*/ uint16(x86_xArgMm),
+ /*7218*/ uint16(x86_xArgMmM64),
+ /*7219*/ uint16(x86_xMatch),
+ /*7220*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
+ /*7222*/ uint16(x86_xReadSlashR),
+ /*7223*/ uint16(x86_xArgXmm1),
+ /*7224*/ uint16(x86_xArgXmm2M128),
+ /*7225*/ uint16(x86_xMatch),
+ /*7226*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7238,
+ 0x0, 7232,
+ /*7232*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
+ /*7234*/ uint16(x86_xReadSlashR),
+ /*7235*/ uint16(x86_xArgMm),
+ /*7236*/ uint16(x86_xArgMmM64),
+ /*7237*/ uint16(x86_xMatch),
+ /*7238*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
+ /*7240*/ uint16(x86_xReadSlashR),
+ /*7241*/ uint16(x86_xArgXmm1),
+ /*7242*/ uint16(x86_xArgXmm2M128),
+ /*7243*/ uint16(x86_xMatch),
+ /*7244*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7256,
+ 0x0, 7250,
+ /*7250*/ uint16(x86_xSetOp), uint16(x86_PADDQ),
+ /*7252*/ uint16(x86_xReadSlashR),
+ /*7253*/ uint16(x86_xArgMm1),
+ /*7254*/ uint16(x86_xArgMm2M64),
+ /*7255*/ uint16(x86_xMatch),
+ /*7256*/ uint16(x86_xSetOp), uint16(x86_PADDQ),
+ /*7258*/ uint16(x86_xReadSlashR),
+ /*7259*/ uint16(x86_xArgXmm1),
+ /*7260*/ uint16(x86_xArgXmm2M128),
+ /*7261*/ uint16(x86_xMatch),
+ /*7262*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7274,
+ 0x0, 7268,
+ /*7268*/ uint16(x86_xSetOp), uint16(x86_PMULLW),
+ /*7270*/ uint16(x86_xReadSlashR),
+ /*7271*/ uint16(x86_xArgMm),
+ /*7272*/ uint16(x86_xArgMmM64),
+ /*7273*/ uint16(x86_xMatch),
+ /*7274*/ uint16(x86_xSetOp), uint16(x86_PMULLW),
+ /*7276*/ uint16(x86_xReadSlashR),
+ /*7277*/ uint16(x86_xArgXmm1),
+ /*7278*/ uint16(x86_xArgXmm2M128),
+ /*7279*/ uint16(x86_xMatch),
+ /*7280*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 7300,
+ 0xF2, 7294,
+ 0x66, 7288,
+ /*7288*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
+ /*7290*/ uint16(x86_xReadSlashR),
+ /*7291*/ uint16(x86_xArgXmm2M64),
+ /*7292*/ uint16(x86_xArgXmm1),
+ /*7293*/ uint16(x86_xMatch),
+ /*7294*/ uint16(x86_xSetOp), uint16(x86_MOVDQ2Q),
+ /*7296*/ uint16(x86_xReadSlashR),
+ /*7297*/ uint16(x86_xArgMm),
+ /*7298*/ uint16(x86_xArgXmm2),
+ /*7299*/ uint16(x86_xMatch),
+ /*7300*/ uint16(x86_xSetOp), uint16(x86_MOVQ2DQ),
+ /*7302*/ uint16(x86_xReadSlashR),
+ /*7303*/ uint16(x86_xArgXmm1),
+ /*7304*/ uint16(x86_xArgMm2),
+ /*7305*/ uint16(x86_xMatch),
+ /*7306*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7318,
+ 0x0, 7312,
+ /*7312*/ uint16(x86_xSetOp), uint16(x86_PMOVMSKB),
+ /*7314*/ uint16(x86_xReadSlashR),
+ /*7315*/ uint16(x86_xArgR32),
+ /*7316*/ uint16(x86_xArgMm2),
+ /*7317*/ uint16(x86_xMatch),
+ /*7318*/ uint16(x86_xSetOp), uint16(x86_PMOVMSKB),
+ /*7320*/ uint16(x86_xReadSlashR),
+ /*7321*/ uint16(x86_xArgR32),
+ /*7322*/ uint16(x86_xArgXmm2),
+ /*7323*/ uint16(x86_xMatch),
+ /*7324*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7336,
+ 0x0, 7330,
+ /*7330*/ uint16(x86_xSetOp), uint16(x86_PSUBUSB),
+ /*7332*/ uint16(x86_xReadSlashR),
+ /*7333*/ uint16(x86_xArgMm),
+ /*7334*/ uint16(x86_xArgMmM64),
+ /*7335*/ uint16(x86_xMatch),
+ /*7336*/ uint16(x86_xSetOp), uint16(x86_PSUBUSB),
+ /*7338*/ uint16(x86_xReadSlashR),
+ /*7339*/ uint16(x86_xArgXmm1),
+ /*7340*/ uint16(x86_xArgXmm2M128),
+ /*7341*/ uint16(x86_xMatch),
+ /*7342*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7354,
+ 0x0, 7348,
+ /*7348*/ uint16(x86_xSetOp), uint16(x86_PSUBUSW),
+ /*7350*/ uint16(x86_xReadSlashR),
+ /*7351*/ uint16(x86_xArgMm),
+ /*7352*/ uint16(x86_xArgMmM64),
+ /*7353*/ uint16(x86_xMatch),
+ /*7354*/ uint16(x86_xSetOp), uint16(x86_PSUBUSW),
+ /*7356*/ uint16(x86_xReadSlashR),
+ /*7357*/ uint16(x86_xArgXmm1),
+ /*7358*/ uint16(x86_xArgXmm2M128),
+ /*7359*/ uint16(x86_xMatch),
+ /*7360*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7372,
+ 0x0, 7366,
+ /*7366*/ uint16(x86_xSetOp), uint16(x86_PMINUB),
+ /*7368*/ uint16(x86_xReadSlashR),
+ /*7369*/ uint16(x86_xArgMm1),
+ /*7370*/ uint16(x86_xArgMm2M64),
+ /*7371*/ uint16(x86_xMatch),
+ /*7372*/ uint16(x86_xSetOp), uint16(x86_PMINUB),
+ /*7374*/ uint16(x86_xReadSlashR),
+ /*7375*/ uint16(x86_xArgXmm1),
+ /*7376*/ uint16(x86_xArgXmm2M128),
+ /*7377*/ uint16(x86_xMatch),
+ /*7378*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7390,
+ 0x0, 7384,
+ /*7384*/ uint16(x86_xSetOp), uint16(x86_PAND),
+ /*7386*/ uint16(x86_xReadSlashR),
+ /*7387*/ uint16(x86_xArgMm),
+ /*7388*/ uint16(x86_xArgMmM64),
+ /*7389*/ uint16(x86_xMatch),
+ /*7390*/ uint16(x86_xSetOp), uint16(x86_PAND),
+ /*7392*/ uint16(x86_xReadSlashR),
+ /*7393*/ uint16(x86_xArgXmm1),
+ /*7394*/ uint16(x86_xArgXmm2M128),
+ /*7395*/ uint16(x86_xMatch),
+ /*7396*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7408,
+ 0x0, 7402,
+ /*7402*/ uint16(x86_xSetOp), uint16(x86_PADDUSB),
+ /*7404*/ uint16(x86_xReadSlashR),
+ /*7405*/ uint16(x86_xArgMm),
+ /*7406*/ uint16(x86_xArgMmM64),
+ /*7407*/ uint16(x86_xMatch),
+ /*7408*/ uint16(x86_xSetOp), uint16(x86_PADDUSB),
+ /*7410*/ uint16(x86_xReadSlashR),
+ /*7411*/ uint16(x86_xArgXmm1),
+ /*7412*/ uint16(x86_xArgXmm2M128),
+ /*7413*/ uint16(x86_xMatch),
+ /*7414*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7426,
+ 0x0, 7420,
+ /*7420*/ uint16(x86_xSetOp), uint16(x86_PADDUSW),
+ /*7422*/ uint16(x86_xReadSlashR),
+ /*7423*/ uint16(x86_xArgMm),
+ /*7424*/ uint16(x86_xArgMmM64),
+ /*7425*/ uint16(x86_xMatch),
+ /*7426*/ uint16(x86_xSetOp), uint16(x86_PADDUSW),
+ /*7428*/ uint16(x86_xReadSlashR),
+ /*7429*/ uint16(x86_xArgXmm1),
+ /*7430*/ uint16(x86_xArgXmm2M128),
+ /*7431*/ uint16(x86_xMatch),
+ /*7432*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7444,
+ 0x0, 7438,
+ /*7438*/ uint16(x86_xSetOp), uint16(x86_PMAXUB),
+ /*7440*/ uint16(x86_xReadSlashR),
+ /*7441*/ uint16(x86_xArgMm1),
+ /*7442*/ uint16(x86_xArgMm2M64),
+ /*7443*/ uint16(x86_xMatch),
+ /*7444*/ uint16(x86_xSetOp), uint16(x86_PMAXUB),
+ /*7446*/ uint16(x86_xReadSlashR),
+ /*7447*/ uint16(x86_xArgXmm1),
+ /*7448*/ uint16(x86_xArgXmm2M128),
+ /*7449*/ uint16(x86_xMatch),
+ /*7450*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7462,
+ 0x0, 7456,
+ /*7456*/ uint16(x86_xSetOp), uint16(x86_PANDN),
+ /*7458*/ uint16(x86_xReadSlashR),
+ /*7459*/ uint16(x86_xArgMm),
+ /*7460*/ uint16(x86_xArgMmM64),
+ /*7461*/ uint16(x86_xMatch),
+ /*7462*/ uint16(x86_xSetOp), uint16(x86_PANDN),
+ /*7464*/ uint16(x86_xReadSlashR),
+ /*7465*/ uint16(x86_xArgXmm1),
+ /*7466*/ uint16(x86_xArgXmm2M128),
+ /*7467*/ uint16(x86_xMatch),
+ /*7468*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7480,
+ 0x0, 7474,
+ /*7474*/ uint16(x86_xSetOp), uint16(x86_PAVGB),
+ /*7476*/ uint16(x86_xReadSlashR),
+ /*7477*/ uint16(x86_xArgMm1),
+ /*7478*/ uint16(x86_xArgMm2M64),
+ /*7479*/ uint16(x86_xMatch),
+ /*7480*/ uint16(x86_xSetOp), uint16(x86_PAVGB),
+ /*7482*/ uint16(x86_xReadSlashR),
+ /*7483*/ uint16(x86_xArgXmm1),
+ /*7484*/ uint16(x86_xArgXmm2M128),
+ /*7485*/ uint16(x86_xMatch),
+ /*7486*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7498,
+ 0x0, 7492,
+ /*7492*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
+ /*7494*/ uint16(x86_xReadSlashR),
+ /*7495*/ uint16(x86_xArgMm),
+ /*7496*/ uint16(x86_xArgMmM64),
+ /*7497*/ uint16(x86_xMatch),
+ /*7498*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
+ /*7500*/ uint16(x86_xReadSlashR),
+ /*7501*/ uint16(x86_xArgXmm1),
+ /*7502*/ uint16(x86_xArgXmm2M128),
+ /*7503*/ uint16(x86_xMatch),
+ /*7504*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7516,
+ 0x0, 7510,
+ /*7510*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
+ /*7512*/ uint16(x86_xReadSlashR),
+ /*7513*/ uint16(x86_xArgMm),
+ /*7514*/ uint16(x86_xArgMmM64),
+ /*7515*/ uint16(x86_xMatch),
+ /*7516*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
+ /*7518*/ uint16(x86_xReadSlashR),
+ /*7519*/ uint16(x86_xArgXmm1),
+ /*7520*/ uint16(x86_xArgXmm2M128),
+ /*7521*/ uint16(x86_xMatch),
+ /*7522*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7534,
+ 0x0, 7528,
+ /*7528*/ uint16(x86_xSetOp), uint16(x86_PAVGW),
+ /*7530*/ uint16(x86_xReadSlashR),
+ /*7531*/ uint16(x86_xArgMm1),
+ /*7532*/ uint16(x86_xArgMm2M64),
+ /*7533*/ uint16(x86_xMatch),
+ /*7534*/ uint16(x86_xSetOp), uint16(x86_PAVGW),
+ /*7536*/ uint16(x86_xReadSlashR),
+ /*7537*/ uint16(x86_xArgXmm1),
+ /*7538*/ uint16(x86_xArgXmm2M128),
+ /*7539*/ uint16(x86_xMatch),
+ /*7540*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7552,
+ 0x0, 7546,
+ /*7546*/ uint16(x86_xSetOp), uint16(x86_PMULHUW),
+ /*7548*/ uint16(x86_xReadSlashR),
+ /*7549*/ uint16(x86_xArgMm1),
+ /*7550*/ uint16(x86_xArgMm2M64),
+ /*7551*/ uint16(x86_xMatch),
+ /*7552*/ uint16(x86_xSetOp), uint16(x86_PMULHUW),
+ /*7554*/ uint16(x86_xReadSlashR),
+ /*7555*/ uint16(x86_xArgXmm1),
+ /*7556*/ uint16(x86_xArgXmm2M128),
+ /*7557*/ uint16(x86_xMatch),
+ /*7558*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7570,
+ 0x0, 7564,
+ /*7564*/ uint16(x86_xSetOp), uint16(x86_PMULHW),
+ /*7566*/ uint16(x86_xReadSlashR),
+ /*7567*/ uint16(x86_xArgMm),
+ /*7568*/ uint16(x86_xArgMmM64),
+ /*7569*/ uint16(x86_xMatch),
+ /*7570*/ uint16(x86_xSetOp), uint16(x86_PMULHW),
+ /*7572*/ uint16(x86_xReadSlashR),
+ /*7573*/ uint16(x86_xArgXmm1),
+ /*7574*/ uint16(x86_xArgXmm2M128),
+ /*7575*/ uint16(x86_xMatch),
+ /*7576*/ uint16(x86_xCondPrefix), 3,
+ 0xF3, 7596,
+ 0xF2, 7590,
+ 0x66, 7584,
+ /*7584*/ uint16(x86_xSetOp), uint16(x86_CVTTPD2DQ),
+ /*7586*/ uint16(x86_xReadSlashR),
+ /*7587*/ uint16(x86_xArgXmm1),
+ /*7588*/ uint16(x86_xArgXmm2M128),
+ /*7589*/ uint16(x86_xMatch),
+ /*7590*/ uint16(x86_xSetOp), uint16(x86_CVTPD2DQ),
+ /*7592*/ uint16(x86_xReadSlashR),
+ /*7593*/ uint16(x86_xArgXmm1),
+ /*7594*/ uint16(x86_xArgXmm2M128),
+ /*7595*/ uint16(x86_xMatch),
+ /*7596*/ uint16(x86_xSetOp), uint16(x86_CVTDQ2PD),
+ /*7598*/ uint16(x86_xReadSlashR),
+ /*7599*/ uint16(x86_xArgXmm1),
+ /*7600*/ uint16(x86_xArgXmm2M64),
+ /*7601*/ uint16(x86_xMatch),
+ /*7602*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7614,
+ 0x0, 7608,
+ /*7608*/ uint16(x86_xSetOp), uint16(x86_MOVNTQ),
+ /*7610*/ uint16(x86_xReadSlashR),
+ /*7611*/ uint16(x86_xArgM64),
+ /*7612*/ uint16(x86_xArgMm),
+ /*7613*/ uint16(x86_xMatch),
+ /*7614*/ uint16(x86_xSetOp), uint16(x86_MOVNTDQ),
+ /*7616*/ uint16(x86_xReadSlashR),
+ /*7617*/ uint16(x86_xArgM128),
+ /*7618*/ uint16(x86_xArgXmm),
+ /*7619*/ uint16(x86_xMatch),
+ /*7620*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7632,
+ 0x0, 7626,
+ /*7626*/ uint16(x86_xSetOp), uint16(x86_PSUBSB),
+ /*7628*/ uint16(x86_xReadSlashR),
+ /*7629*/ uint16(x86_xArgMm),
+ /*7630*/ uint16(x86_xArgMmM64),
+ /*7631*/ uint16(x86_xMatch),
+ /*7632*/ uint16(x86_xSetOp), uint16(x86_PSUBSB),
+ /*7634*/ uint16(x86_xReadSlashR),
+ /*7635*/ uint16(x86_xArgXmm1),
+ /*7636*/ uint16(x86_xArgXmm2M128),
+ /*7637*/ uint16(x86_xMatch),
+ /*7638*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7650,
+ 0x0, 7644,
+ /*7644*/ uint16(x86_xSetOp), uint16(x86_PSUBSW),
+ /*7646*/ uint16(x86_xReadSlashR),
+ /*7647*/ uint16(x86_xArgMm),
+ /*7648*/ uint16(x86_xArgMmM64),
+ /*7649*/ uint16(x86_xMatch),
+ /*7650*/ uint16(x86_xSetOp), uint16(x86_PSUBSW),
+ /*7652*/ uint16(x86_xReadSlashR),
+ /*7653*/ uint16(x86_xArgXmm1),
+ /*7654*/ uint16(x86_xArgXmm2M128),
+ /*7655*/ uint16(x86_xMatch),
+ /*7656*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7668,
+ 0x0, 7662,
+ /*7662*/ uint16(x86_xSetOp), uint16(x86_PMINSW),
+ /*7664*/ uint16(x86_xReadSlashR),
+ /*7665*/ uint16(x86_xArgMm1),
+ /*7666*/ uint16(x86_xArgMm2M64),
+ /*7667*/ uint16(x86_xMatch),
+ /*7668*/ uint16(x86_xSetOp), uint16(x86_PMINSW),
+ /*7670*/ uint16(x86_xReadSlashR),
+ /*7671*/ uint16(x86_xArgXmm1),
+ /*7672*/ uint16(x86_xArgXmm2M128),
+ /*7673*/ uint16(x86_xMatch),
+ /*7674*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7686,
+ 0x0, 7680,
+ /*7680*/ uint16(x86_xSetOp), uint16(x86_POR),
+ /*7682*/ uint16(x86_xReadSlashR),
+ /*7683*/ uint16(x86_xArgMm),
+ /*7684*/ uint16(x86_xArgMmM64),
+ /*7685*/ uint16(x86_xMatch),
+ /*7686*/ uint16(x86_xSetOp), uint16(x86_POR),
+ /*7688*/ uint16(x86_xReadSlashR),
+ /*7689*/ uint16(x86_xArgXmm1),
+ /*7690*/ uint16(x86_xArgXmm2M128),
+ /*7691*/ uint16(x86_xMatch),
+ /*7692*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7704,
+ 0x0, 7698,
+ /*7698*/ uint16(x86_xSetOp), uint16(x86_PADDSB),
+ /*7700*/ uint16(x86_xReadSlashR),
+ /*7701*/ uint16(x86_xArgMm),
+ /*7702*/ uint16(x86_xArgMmM64),
+ /*7703*/ uint16(x86_xMatch),
+ /*7704*/ uint16(x86_xSetOp), uint16(x86_PADDSB),
+ /*7706*/ uint16(x86_xReadSlashR),
+ /*7707*/ uint16(x86_xArgXmm1),
+ /*7708*/ uint16(x86_xArgXmm2M128),
+ /*7709*/ uint16(x86_xMatch),
+ /*7710*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7722,
+ 0x0, 7716,
+ /*7716*/ uint16(x86_xSetOp), uint16(x86_PADDSW),
+ /*7718*/ uint16(x86_xReadSlashR),
+ /*7719*/ uint16(x86_xArgMm),
+ /*7720*/ uint16(x86_xArgMmM64),
+ /*7721*/ uint16(x86_xMatch),
+ /*7722*/ uint16(x86_xSetOp), uint16(x86_PADDSW),
+ /*7724*/ uint16(x86_xReadSlashR),
+ /*7725*/ uint16(x86_xArgXmm1),
+ /*7726*/ uint16(x86_xArgXmm2M128),
+ /*7727*/ uint16(x86_xMatch),
+ /*7728*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7740,
+ 0x0, 7734,
+ /*7734*/ uint16(x86_xSetOp), uint16(x86_PMAXSW),
+ /*7736*/ uint16(x86_xReadSlashR),
+ /*7737*/ uint16(x86_xArgMm1),
+ /*7738*/ uint16(x86_xArgMm2M64),
+ /*7739*/ uint16(x86_xMatch),
+ /*7740*/ uint16(x86_xSetOp), uint16(x86_PMAXSW),
+ /*7742*/ uint16(x86_xReadSlashR),
+ /*7743*/ uint16(x86_xArgXmm1),
+ /*7744*/ uint16(x86_xArgXmm2M128),
+ /*7745*/ uint16(x86_xMatch),
+ /*7746*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7758,
+ 0x0, 7752,
+ /*7752*/ uint16(x86_xSetOp), uint16(x86_PXOR),
+ /*7754*/ uint16(x86_xReadSlashR),
+ /*7755*/ uint16(x86_xArgMm),
+ /*7756*/ uint16(x86_xArgMmM64),
+ /*7757*/ uint16(x86_xMatch),
+ /*7758*/ uint16(x86_xSetOp), uint16(x86_PXOR),
+ /*7760*/ uint16(x86_xReadSlashR),
+ /*7761*/ uint16(x86_xArgXmm1),
+ /*7762*/ uint16(x86_xArgXmm2M128),
+ /*7763*/ uint16(x86_xMatch),
+ /*7764*/ uint16(x86_xCondPrefix), 1,
+ 0xF2, 7768,
+ /*7768*/ uint16(x86_xSetOp), uint16(x86_LDDQU),
+ /*7770*/ uint16(x86_xReadSlashR),
+ /*7771*/ uint16(x86_xArgXmm1),
+ /*7772*/ uint16(x86_xArgM128),
+ /*7773*/ uint16(x86_xMatch),
+ /*7774*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7786,
+ 0x0, 7780,
+ /*7780*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
+ /*7782*/ uint16(x86_xReadSlashR),
+ /*7783*/ uint16(x86_xArgMm),
+ /*7784*/ uint16(x86_xArgMmM64),
+ /*7785*/ uint16(x86_xMatch),
+ /*7786*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
+ /*7788*/ uint16(x86_xReadSlashR),
+ /*7789*/ uint16(x86_xArgXmm1),
+ /*7790*/ uint16(x86_xArgXmm2M128),
+ /*7791*/ uint16(x86_xMatch),
+ /*7792*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7804,
+ 0x0, 7798,
+ /*7798*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
+ /*7800*/ uint16(x86_xReadSlashR),
+ /*7801*/ uint16(x86_xArgMm),
+ /*7802*/ uint16(x86_xArgMmM64),
+ /*7803*/ uint16(x86_xMatch),
+ /*7804*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
+ /*7806*/ uint16(x86_xReadSlashR),
+ /*7807*/ uint16(x86_xArgXmm1),
+ /*7808*/ uint16(x86_xArgXmm2M128),
+ /*7809*/ uint16(x86_xMatch),
+ /*7810*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7822,
+ 0x0, 7816,
+ /*7816*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
+ /*7818*/ uint16(x86_xReadSlashR),
+ /*7819*/ uint16(x86_xArgMm),
+ /*7820*/ uint16(x86_xArgMmM64),
+ /*7821*/ uint16(x86_xMatch),
+ /*7822*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
+ /*7824*/ uint16(x86_xReadSlashR),
+ /*7825*/ uint16(x86_xArgXmm1),
+ /*7826*/ uint16(x86_xArgXmm2M128),
+ /*7827*/ uint16(x86_xMatch),
+ /*7828*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7840,
+ 0x0, 7834,
+ /*7834*/ uint16(x86_xSetOp), uint16(x86_PMULUDQ),
+ /*7836*/ uint16(x86_xReadSlashR),
+ /*7837*/ uint16(x86_xArgMm1),
+ /*7838*/ uint16(x86_xArgMm2M64),
+ /*7839*/ uint16(x86_xMatch),
+ /*7840*/ uint16(x86_xSetOp), uint16(x86_PMULUDQ),
+ /*7842*/ uint16(x86_xReadSlashR),
+ /*7843*/ uint16(x86_xArgXmm1),
+ /*7844*/ uint16(x86_xArgXmm2M128),
+ /*7845*/ uint16(x86_xMatch),
+ /*7846*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7858,
+ 0x0, 7852,
+ /*7852*/ uint16(x86_xSetOp), uint16(x86_PMADDWD),
+ /*7854*/ uint16(x86_xReadSlashR),
+ /*7855*/ uint16(x86_xArgMm),
+ /*7856*/ uint16(x86_xArgMmM64),
+ /*7857*/ uint16(x86_xMatch),
+ /*7858*/ uint16(x86_xSetOp), uint16(x86_PMADDWD),
+ /*7860*/ uint16(x86_xReadSlashR),
+ /*7861*/ uint16(x86_xArgXmm1),
+ /*7862*/ uint16(x86_xArgXmm2M128),
+ /*7863*/ uint16(x86_xMatch),
+ /*7864*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7876,
+ 0x0, 7870,
+ /*7870*/ uint16(x86_xSetOp), uint16(x86_PSADBW),
+ /*7872*/ uint16(x86_xReadSlashR),
+ /*7873*/ uint16(x86_xArgMm1),
+ /*7874*/ uint16(x86_xArgMm2M64),
+ /*7875*/ uint16(x86_xMatch),
+ /*7876*/ uint16(x86_xSetOp), uint16(x86_PSADBW),
+ /*7878*/ uint16(x86_xReadSlashR),
+ /*7879*/ uint16(x86_xArgXmm1),
+ /*7880*/ uint16(x86_xArgXmm2M128),
+ /*7881*/ uint16(x86_xMatch),
+ /*7882*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7894,
+ 0x0, 7888,
+ /*7888*/ uint16(x86_xSetOp), uint16(x86_MASKMOVQ),
+ /*7890*/ uint16(x86_xReadSlashR),
+ /*7891*/ uint16(x86_xArgMm1),
+ /*7892*/ uint16(x86_xArgMm2),
+ /*7893*/ uint16(x86_xMatch),
+ /*7894*/ uint16(x86_xSetOp), uint16(x86_MASKMOVDQU),
+ /*7896*/ uint16(x86_xReadSlashR),
+ /*7897*/ uint16(x86_xArgXmm1),
+ /*7898*/ uint16(x86_xArgXmm2),
+ /*7899*/ uint16(x86_xMatch),
+ /*7900*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7912,
+ 0x0, 7906,
+ /*7906*/ uint16(x86_xSetOp), uint16(x86_PSUBB),
+ /*7908*/ uint16(x86_xReadSlashR),
+ /*7909*/ uint16(x86_xArgMm),
+ /*7910*/ uint16(x86_xArgMmM64),
+ /*7911*/ uint16(x86_xMatch),
+ /*7912*/ uint16(x86_xSetOp), uint16(x86_PSUBB),
+ /*7914*/ uint16(x86_xReadSlashR),
+ /*7915*/ uint16(x86_xArgXmm1),
+ /*7916*/ uint16(x86_xArgXmm2M128),
+ /*7917*/ uint16(x86_xMatch),
+ /*7918*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7930,
+ 0x0, 7924,
+ /*7924*/ uint16(x86_xSetOp), uint16(x86_PSUBW),
+ /*7926*/ uint16(x86_xReadSlashR),
+ /*7927*/ uint16(x86_xArgMm),
+ /*7928*/ uint16(x86_xArgMmM64),
+ /*7929*/ uint16(x86_xMatch),
+ /*7930*/ uint16(x86_xSetOp), uint16(x86_PSUBW),
+ /*7932*/ uint16(x86_xReadSlashR),
+ /*7933*/ uint16(x86_xArgXmm1),
+ /*7934*/ uint16(x86_xArgXmm2M128),
+ /*7935*/ uint16(x86_xMatch),
+ /*7936*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7948,
+ 0x0, 7942,
+ /*7942*/ uint16(x86_xSetOp), uint16(x86_PSUBD),
+ /*7944*/ uint16(x86_xReadSlashR),
+ /*7945*/ uint16(x86_xArgMm),
+ /*7946*/ uint16(x86_xArgMmM64),
+ /*7947*/ uint16(x86_xMatch),
+ /*7948*/ uint16(x86_xSetOp), uint16(x86_PSUBD),
+ /*7950*/ uint16(x86_xReadSlashR),
+ /*7951*/ uint16(x86_xArgXmm1),
+ /*7952*/ uint16(x86_xArgXmm2M128),
+ /*7953*/ uint16(x86_xMatch),
+ /*7954*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7966,
+ 0x0, 7960,
+ /*7960*/ uint16(x86_xSetOp), uint16(x86_PSUBQ),
+ /*7962*/ uint16(x86_xReadSlashR),
+ /*7963*/ uint16(x86_xArgMm1),
+ /*7964*/ uint16(x86_xArgMm2M64),
+ /*7965*/ uint16(x86_xMatch),
+ /*7966*/ uint16(x86_xSetOp), uint16(x86_PSUBQ),
+ /*7968*/ uint16(x86_xReadSlashR),
+ /*7969*/ uint16(x86_xArgXmm1),
+ /*7970*/ uint16(x86_xArgXmm2M128),
+ /*7971*/ uint16(x86_xMatch),
+ /*7972*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 7984,
+ 0x0, 7978,
+ /*7978*/ uint16(x86_xSetOp), uint16(x86_PADDB),
+ /*7980*/ uint16(x86_xReadSlashR),
+ /*7981*/ uint16(x86_xArgMm),
+ /*7982*/ uint16(x86_xArgMmM64),
+ /*7983*/ uint16(x86_xMatch),
+ /*7984*/ uint16(x86_xSetOp), uint16(x86_PADDB),
+ /*7986*/ uint16(x86_xReadSlashR),
+ /*7987*/ uint16(x86_xArgXmm1),
+ /*7988*/ uint16(x86_xArgXmm2M128),
+ /*7989*/ uint16(x86_xMatch),
+ /*7990*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 8002,
+ 0x0, 7996,
+ /*7996*/ uint16(x86_xSetOp), uint16(x86_PADDW),
+ /*7998*/ uint16(x86_xReadSlashR),
+ /*7999*/ uint16(x86_xArgMm),
+ /*8000*/ uint16(x86_xArgMmM64),
+ /*8001*/ uint16(x86_xMatch),
+ /*8002*/ uint16(x86_xSetOp), uint16(x86_PADDW),
+ /*8004*/ uint16(x86_xReadSlashR),
+ /*8005*/ uint16(x86_xArgXmm1),
+ /*8006*/ uint16(x86_xArgXmm2M128),
+ /*8007*/ uint16(x86_xMatch),
+ /*8008*/ uint16(x86_xCondPrefix), 2,
+ 0x66, 8020,
+ 0x0, 8014,
+ /*8014*/ uint16(x86_xSetOp), uint16(x86_PADDD),
+ /*8016*/ uint16(x86_xReadSlashR),
+ /*8017*/ uint16(x86_xArgMm),
+ /*8018*/ uint16(x86_xArgMmM64),
+ /*8019*/ uint16(x86_xMatch),
+ /*8020*/ uint16(x86_xSetOp), uint16(x86_PADDD),
+ /*8022*/ uint16(x86_xReadSlashR),
+ /*8023*/ uint16(x86_xArgXmm1),
+ /*8024*/ uint16(x86_xArgXmm2M128),
+ /*8025*/ uint16(x86_xMatch),
+ /*8026*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8028*/ uint16(x86_xReadSlashR),
+ /*8029*/ uint16(x86_xArgRM8),
+ /*8030*/ uint16(x86_xArgR8),
+ /*8031*/ uint16(x86_xMatch),
+ /*8032*/ uint16(x86_xCondIs64), 8035, 8051,
+ /*8035*/ uint16(x86_xCondDataSize), 8039, 8045, 0,
+ /*8039*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8041*/ uint16(x86_xReadSlashR),
+ /*8042*/ uint16(x86_xArgRM16),
+ /*8043*/ uint16(x86_xArgR16),
+ /*8044*/ uint16(x86_xMatch),
+ /*8045*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8047*/ uint16(x86_xReadSlashR),
+ /*8048*/ uint16(x86_xArgRM32),
+ /*8049*/ uint16(x86_xArgR32),
+ /*8050*/ uint16(x86_xMatch),
+ /*8051*/ uint16(x86_xCondDataSize), 8039, 8045, 8055,
+ /*8055*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8057*/ uint16(x86_xReadSlashR),
+ /*8058*/ uint16(x86_xArgRM64),
+ /*8059*/ uint16(x86_xArgR64),
+ /*8060*/ uint16(x86_xMatch),
+ /*8061*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8063*/ uint16(x86_xReadSlashR),
+ /*8064*/ uint16(x86_xArgR8),
+ /*8065*/ uint16(x86_xArgRM8),
+ /*8066*/ uint16(x86_xMatch),
+ /*8067*/ uint16(x86_xCondIs64), 8070, 8086,
+ /*8070*/ uint16(x86_xCondDataSize), 8074, 8080, 0,
+ /*8074*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8076*/ uint16(x86_xReadSlashR),
+ /*8077*/ uint16(x86_xArgR16),
+ /*8078*/ uint16(x86_xArgRM16),
+ /*8079*/ uint16(x86_xMatch),
+ /*8080*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8082*/ uint16(x86_xReadSlashR),
+ /*8083*/ uint16(x86_xArgR32),
+ /*8084*/ uint16(x86_xArgRM32),
+ /*8085*/ uint16(x86_xMatch),
+ /*8086*/ uint16(x86_xCondDataSize), 8074, 8080, 8090,
+ /*8090*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8092*/ uint16(x86_xReadSlashR),
+ /*8093*/ uint16(x86_xArgR64),
+ /*8094*/ uint16(x86_xArgRM64),
+ /*8095*/ uint16(x86_xMatch),
+ /*8096*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8098*/ uint16(x86_xReadIb),
+ /*8099*/ uint16(x86_xArgAL),
+ /*8100*/ uint16(x86_xArgImm8u),
+ /*8101*/ uint16(x86_xMatch),
+ /*8102*/ uint16(x86_xCondIs64), 8105, 8121,
+ /*8105*/ uint16(x86_xCondDataSize), 8109, 8115, 0,
+ /*8109*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8111*/ uint16(x86_xReadIw),
+ /*8112*/ uint16(x86_xArgAX),
+ /*8113*/ uint16(x86_xArgImm16),
+ /*8114*/ uint16(x86_xMatch),
+ /*8115*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8117*/ uint16(x86_xReadId),
+ /*8118*/ uint16(x86_xArgEAX),
+ /*8119*/ uint16(x86_xArgImm32),
+ /*8120*/ uint16(x86_xMatch),
+ /*8121*/ uint16(x86_xCondDataSize), 8109, 8115, 8125,
+ /*8125*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*8127*/ uint16(x86_xReadId),
+ /*8128*/ uint16(x86_xArgRAX),
+ /*8129*/ uint16(x86_xArgImm32),
+ /*8130*/ uint16(x86_xMatch),
+ /*8131*/ uint16(x86_xCondIs64), 8134, 0,
+ /*8134*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8136*/ uint16(x86_xArgSS),
+ /*8137*/ uint16(x86_xMatch),
+ /*8138*/ uint16(x86_xCondIs64), 8141, 0,
+ /*8141*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*8143*/ uint16(x86_xArgSS),
+ /*8144*/ uint16(x86_xMatch),
+ /*8145*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8147*/ uint16(x86_xReadSlashR),
+ /*8148*/ uint16(x86_xArgRM8),
+ /*8149*/ uint16(x86_xArgR8),
+ /*8150*/ uint16(x86_xMatch),
+ /*8151*/ uint16(x86_xCondIs64), 8154, 8170,
+ /*8154*/ uint16(x86_xCondDataSize), 8158, 8164, 0,
+ /*8158*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8160*/ uint16(x86_xReadSlashR),
+ /*8161*/ uint16(x86_xArgRM16),
+ /*8162*/ uint16(x86_xArgR16),
+ /*8163*/ uint16(x86_xMatch),
+ /*8164*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8166*/ uint16(x86_xReadSlashR),
+ /*8167*/ uint16(x86_xArgRM32),
+ /*8168*/ uint16(x86_xArgR32),
+ /*8169*/ uint16(x86_xMatch),
+ /*8170*/ uint16(x86_xCondDataSize), 8158, 8164, 8174,
+ /*8174*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8176*/ uint16(x86_xReadSlashR),
+ /*8177*/ uint16(x86_xArgRM64),
+ /*8178*/ uint16(x86_xArgR64),
+ /*8179*/ uint16(x86_xMatch),
+ /*8180*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8182*/ uint16(x86_xReadSlashR),
+ /*8183*/ uint16(x86_xArgR8),
+ /*8184*/ uint16(x86_xArgRM8),
+ /*8185*/ uint16(x86_xMatch),
+ /*8186*/ uint16(x86_xCondIs64), 8189, 8205,
+ /*8189*/ uint16(x86_xCondDataSize), 8193, 8199, 0,
+ /*8193*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8195*/ uint16(x86_xReadSlashR),
+ /*8196*/ uint16(x86_xArgR16),
+ /*8197*/ uint16(x86_xArgRM16),
+ /*8198*/ uint16(x86_xMatch),
+ /*8199*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8201*/ uint16(x86_xReadSlashR),
+ /*8202*/ uint16(x86_xArgR32),
+ /*8203*/ uint16(x86_xArgRM32),
+ /*8204*/ uint16(x86_xMatch),
+ /*8205*/ uint16(x86_xCondDataSize), 8193, 8199, 8209,
+ /*8209*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8211*/ uint16(x86_xReadSlashR),
+ /*8212*/ uint16(x86_xArgR64),
+ /*8213*/ uint16(x86_xArgRM64),
+ /*8214*/ uint16(x86_xMatch),
+ /*8215*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8217*/ uint16(x86_xReadIb),
+ /*8218*/ uint16(x86_xArgAL),
+ /*8219*/ uint16(x86_xArgImm8u),
+ /*8220*/ uint16(x86_xMatch),
+ /*8221*/ uint16(x86_xCondIs64), 8224, 8240,
+ /*8224*/ uint16(x86_xCondDataSize), 8228, 8234, 0,
+ /*8228*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8230*/ uint16(x86_xReadIw),
+ /*8231*/ uint16(x86_xArgAX),
+ /*8232*/ uint16(x86_xArgImm16),
+ /*8233*/ uint16(x86_xMatch),
+ /*8234*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8236*/ uint16(x86_xReadId),
+ /*8237*/ uint16(x86_xArgEAX),
+ /*8238*/ uint16(x86_xArgImm32),
+ /*8239*/ uint16(x86_xMatch),
+ /*8240*/ uint16(x86_xCondDataSize), 8228, 8234, 8244,
+ /*8244*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*8246*/ uint16(x86_xReadId),
+ /*8247*/ uint16(x86_xArgRAX),
+ /*8248*/ uint16(x86_xArgImm32),
+ /*8249*/ uint16(x86_xMatch),
+ /*8250*/ uint16(x86_xCondIs64), 8253, 0,
+ /*8253*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8255*/ uint16(x86_xArgDS),
+ /*8256*/ uint16(x86_xMatch),
+ /*8257*/ uint16(x86_xCondIs64), 8260, 0,
+ /*8260*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*8262*/ uint16(x86_xArgDS),
+ /*8263*/ uint16(x86_xMatch),
+ /*8264*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8266*/ uint16(x86_xReadSlashR),
+ /*8267*/ uint16(x86_xArgRM8),
+ /*8268*/ uint16(x86_xArgR8),
+ /*8269*/ uint16(x86_xMatch),
+ /*8270*/ uint16(x86_xCondIs64), 8273, 8289,
+ /*8273*/ uint16(x86_xCondDataSize), 8277, 8283, 0,
+ /*8277*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8279*/ uint16(x86_xReadSlashR),
+ /*8280*/ uint16(x86_xArgRM16),
+ /*8281*/ uint16(x86_xArgR16),
+ /*8282*/ uint16(x86_xMatch),
+ /*8283*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8285*/ uint16(x86_xReadSlashR),
+ /*8286*/ uint16(x86_xArgRM32),
+ /*8287*/ uint16(x86_xArgR32),
+ /*8288*/ uint16(x86_xMatch),
+ /*8289*/ uint16(x86_xCondDataSize), 8277, 8283, 8293,
+ /*8293*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8295*/ uint16(x86_xReadSlashR),
+ /*8296*/ uint16(x86_xArgRM64),
+ /*8297*/ uint16(x86_xArgR64),
+ /*8298*/ uint16(x86_xMatch),
+ /*8299*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8301*/ uint16(x86_xReadSlashR),
+ /*8302*/ uint16(x86_xArgR8),
+ /*8303*/ uint16(x86_xArgRM8),
+ /*8304*/ uint16(x86_xMatch),
+ /*8305*/ uint16(x86_xCondIs64), 8308, 8324,
+ /*8308*/ uint16(x86_xCondDataSize), 8312, 8318, 0,
+ /*8312*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8314*/ uint16(x86_xReadSlashR),
+ /*8315*/ uint16(x86_xArgR16),
+ /*8316*/ uint16(x86_xArgRM16),
+ /*8317*/ uint16(x86_xMatch),
+ /*8318*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8320*/ uint16(x86_xReadSlashR),
+ /*8321*/ uint16(x86_xArgR32),
+ /*8322*/ uint16(x86_xArgRM32),
+ /*8323*/ uint16(x86_xMatch),
+ /*8324*/ uint16(x86_xCondDataSize), 8312, 8318, 8328,
+ /*8328*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8330*/ uint16(x86_xReadSlashR),
+ /*8331*/ uint16(x86_xArgR64),
+ /*8332*/ uint16(x86_xArgRM64),
+ /*8333*/ uint16(x86_xMatch),
+ /*8334*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8336*/ uint16(x86_xReadIb),
+ /*8337*/ uint16(x86_xArgAL),
+ /*8338*/ uint16(x86_xArgImm8u),
+ /*8339*/ uint16(x86_xMatch),
+ /*8340*/ uint16(x86_xCondIs64), 8343, 8359,
+ /*8343*/ uint16(x86_xCondDataSize), 8347, 8353, 0,
+ /*8347*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8349*/ uint16(x86_xReadIw),
+ /*8350*/ uint16(x86_xArgAX),
+ /*8351*/ uint16(x86_xArgImm16),
+ /*8352*/ uint16(x86_xMatch),
+ /*8353*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8355*/ uint16(x86_xReadId),
+ /*8356*/ uint16(x86_xArgEAX),
+ /*8357*/ uint16(x86_xArgImm32),
+ /*8358*/ uint16(x86_xMatch),
+ /*8359*/ uint16(x86_xCondDataSize), 8347, 8353, 8363,
+ /*8363*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*8365*/ uint16(x86_xReadId),
+ /*8366*/ uint16(x86_xArgRAX),
+ /*8367*/ uint16(x86_xArgImm32),
+ /*8368*/ uint16(x86_xMatch),
+ /*8369*/ uint16(x86_xCondIs64), 8372, 0,
+ /*8372*/ uint16(x86_xSetOp), uint16(x86_DAA),
+ /*8374*/ uint16(x86_xMatch),
+ /*8375*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8377*/ uint16(x86_xReadSlashR),
+ /*8378*/ uint16(x86_xArgRM8),
+ /*8379*/ uint16(x86_xArgR8),
+ /*8380*/ uint16(x86_xMatch),
+ /*8381*/ uint16(x86_xCondIs64), 8384, 8400,
+ /*8384*/ uint16(x86_xCondDataSize), 8388, 8394, 0,
+ /*8388*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8390*/ uint16(x86_xReadSlashR),
+ /*8391*/ uint16(x86_xArgRM16),
+ /*8392*/ uint16(x86_xArgR16),
+ /*8393*/ uint16(x86_xMatch),
+ /*8394*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8396*/ uint16(x86_xReadSlashR),
+ /*8397*/ uint16(x86_xArgRM32),
+ /*8398*/ uint16(x86_xArgR32),
+ /*8399*/ uint16(x86_xMatch),
+ /*8400*/ uint16(x86_xCondDataSize), 8388, 8394, 8404,
+ /*8404*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8406*/ uint16(x86_xReadSlashR),
+ /*8407*/ uint16(x86_xArgRM64),
+ /*8408*/ uint16(x86_xArgR64),
+ /*8409*/ uint16(x86_xMatch),
+ /*8410*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8412*/ uint16(x86_xReadSlashR),
+ /*8413*/ uint16(x86_xArgR8),
+ /*8414*/ uint16(x86_xArgRM8),
+ /*8415*/ uint16(x86_xMatch),
+ /*8416*/ uint16(x86_xCondIs64), 8419, 8435,
+ /*8419*/ uint16(x86_xCondDataSize), 8423, 8429, 0,
+ /*8423*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8425*/ uint16(x86_xReadSlashR),
+ /*8426*/ uint16(x86_xArgR16),
+ /*8427*/ uint16(x86_xArgRM16),
+ /*8428*/ uint16(x86_xMatch),
+ /*8429*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8431*/ uint16(x86_xReadSlashR),
+ /*8432*/ uint16(x86_xArgR32),
+ /*8433*/ uint16(x86_xArgRM32),
+ /*8434*/ uint16(x86_xMatch),
+ /*8435*/ uint16(x86_xCondDataSize), 8423, 8429, 8439,
+ /*8439*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8441*/ uint16(x86_xReadSlashR),
+ /*8442*/ uint16(x86_xArgR64),
+ /*8443*/ uint16(x86_xArgRM64),
+ /*8444*/ uint16(x86_xMatch),
+ /*8445*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8447*/ uint16(x86_xReadIb),
+ /*8448*/ uint16(x86_xArgAL),
+ /*8449*/ uint16(x86_xArgImm8u),
+ /*8450*/ uint16(x86_xMatch),
+ /*8451*/ uint16(x86_xCondIs64), 8454, 8470,
+ /*8454*/ uint16(x86_xCondDataSize), 8458, 8464, 0,
+ /*8458*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8460*/ uint16(x86_xReadIw),
+ /*8461*/ uint16(x86_xArgAX),
+ /*8462*/ uint16(x86_xArgImm16),
+ /*8463*/ uint16(x86_xMatch),
+ /*8464*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8466*/ uint16(x86_xReadId),
+ /*8467*/ uint16(x86_xArgEAX),
+ /*8468*/ uint16(x86_xArgImm32),
+ /*8469*/ uint16(x86_xMatch),
+ /*8470*/ uint16(x86_xCondDataSize), 8458, 8464, 8474,
+ /*8474*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*8476*/ uint16(x86_xReadId),
+ /*8477*/ uint16(x86_xArgRAX),
+ /*8478*/ uint16(x86_xArgImm32),
+ /*8479*/ uint16(x86_xMatch),
+ /*8480*/ uint16(x86_xCondIs64), 8483, 0,
+ /*8483*/ uint16(x86_xSetOp), uint16(x86_DAS),
+ /*8485*/ uint16(x86_xMatch),
+ /*8486*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8488*/ uint16(x86_xReadSlashR),
+ /*8489*/ uint16(x86_xArgRM8),
+ /*8490*/ uint16(x86_xArgR8),
+ /*8491*/ uint16(x86_xMatch),
+ /*8492*/ uint16(x86_xCondIs64), 8495, 8511,
+ /*8495*/ uint16(x86_xCondDataSize), 8499, 8505, 0,
+ /*8499*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8501*/ uint16(x86_xReadSlashR),
+ /*8502*/ uint16(x86_xArgRM16),
+ /*8503*/ uint16(x86_xArgR16),
+ /*8504*/ uint16(x86_xMatch),
+ /*8505*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8507*/ uint16(x86_xReadSlashR),
+ /*8508*/ uint16(x86_xArgRM32),
+ /*8509*/ uint16(x86_xArgR32),
+ /*8510*/ uint16(x86_xMatch),
+ /*8511*/ uint16(x86_xCondDataSize), 8499, 8505, 8515,
+ /*8515*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8517*/ uint16(x86_xReadSlashR),
+ /*8518*/ uint16(x86_xArgRM64),
+ /*8519*/ uint16(x86_xArgR64),
+ /*8520*/ uint16(x86_xMatch),
+ /*8521*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8523*/ uint16(x86_xReadSlashR),
+ /*8524*/ uint16(x86_xArgR8),
+ /*8525*/ uint16(x86_xArgRM8),
+ /*8526*/ uint16(x86_xMatch),
+ /*8527*/ uint16(x86_xCondIs64), 8530, 8546,
+ /*8530*/ uint16(x86_xCondDataSize), 8534, 8540, 0,
+ /*8534*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8536*/ uint16(x86_xReadSlashR),
+ /*8537*/ uint16(x86_xArgR16),
+ /*8538*/ uint16(x86_xArgRM16),
+ /*8539*/ uint16(x86_xMatch),
+ /*8540*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8542*/ uint16(x86_xReadSlashR),
+ /*8543*/ uint16(x86_xArgR32),
+ /*8544*/ uint16(x86_xArgRM32),
+ /*8545*/ uint16(x86_xMatch),
+ /*8546*/ uint16(x86_xCondDataSize), 8534, 8540, 8550,
+ /*8550*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8552*/ uint16(x86_xReadSlashR),
+ /*8553*/ uint16(x86_xArgR64),
+ /*8554*/ uint16(x86_xArgRM64),
+ /*8555*/ uint16(x86_xMatch),
+ /*8556*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8558*/ uint16(x86_xReadIb),
+ /*8559*/ uint16(x86_xArgAL),
+ /*8560*/ uint16(x86_xArgImm8u),
+ /*8561*/ uint16(x86_xMatch),
+ /*8562*/ uint16(x86_xCondIs64), 8565, 8581,
+ /*8565*/ uint16(x86_xCondDataSize), 8569, 8575, 0,
+ /*8569*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8571*/ uint16(x86_xReadIw),
+ /*8572*/ uint16(x86_xArgAX),
+ /*8573*/ uint16(x86_xArgImm16),
+ /*8574*/ uint16(x86_xMatch),
+ /*8575*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8577*/ uint16(x86_xReadId),
+ /*8578*/ uint16(x86_xArgEAX),
+ /*8579*/ uint16(x86_xArgImm32),
+ /*8580*/ uint16(x86_xMatch),
+ /*8581*/ uint16(x86_xCondDataSize), 8569, 8575, 8585,
+ /*8585*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*8587*/ uint16(x86_xReadId),
+ /*8588*/ uint16(x86_xArgRAX),
+ /*8589*/ uint16(x86_xArgImm32),
+ /*8590*/ uint16(x86_xMatch),
+ /*8591*/ uint16(x86_xCondIs64), 8594, 0,
+ /*8594*/ uint16(x86_xSetOp), uint16(x86_AAA),
+ /*8596*/ uint16(x86_xMatch),
+ /*8597*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8599*/ uint16(x86_xReadSlashR),
+ /*8600*/ uint16(x86_xArgRM8),
+ /*8601*/ uint16(x86_xArgR8),
+ /*8602*/ uint16(x86_xMatch),
+ /*8603*/ uint16(x86_xCondIs64), 8606, 8622,
+ /*8606*/ uint16(x86_xCondDataSize), 8610, 8616, 0,
+ /*8610*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8612*/ uint16(x86_xReadSlashR),
+ /*8613*/ uint16(x86_xArgRM16),
+ /*8614*/ uint16(x86_xArgR16),
+ /*8615*/ uint16(x86_xMatch),
+ /*8616*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8618*/ uint16(x86_xReadSlashR),
+ /*8619*/ uint16(x86_xArgRM32),
+ /*8620*/ uint16(x86_xArgR32),
+ /*8621*/ uint16(x86_xMatch),
+ /*8622*/ uint16(x86_xCondDataSize), 8610, 8616, 8626,
+ /*8626*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8628*/ uint16(x86_xReadSlashR),
+ /*8629*/ uint16(x86_xArgRM64),
+ /*8630*/ uint16(x86_xArgR64),
+ /*8631*/ uint16(x86_xMatch),
+ /*8632*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8634*/ uint16(x86_xReadSlashR),
+ /*8635*/ uint16(x86_xArgR8),
+ /*8636*/ uint16(x86_xArgRM8),
+ /*8637*/ uint16(x86_xMatch),
+ /*8638*/ uint16(x86_xCondIs64), 8641, 8657,
+ /*8641*/ uint16(x86_xCondDataSize), 8645, 8651, 0,
+ /*8645*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8647*/ uint16(x86_xReadSlashR),
+ /*8648*/ uint16(x86_xArgR16),
+ /*8649*/ uint16(x86_xArgRM16),
+ /*8650*/ uint16(x86_xMatch),
+ /*8651*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8653*/ uint16(x86_xReadSlashR),
+ /*8654*/ uint16(x86_xArgR32),
+ /*8655*/ uint16(x86_xArgRM32),
+ /*8656*/ uint16(x86_xMatch),
+ /*8657*/ uint16(x86_xCondDataSize), 8645, 8651, 8661,
+ /*8661*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8663*/ uint16(x86_xReadSlashR),
+ /*8664*/ uint16(x86_xArgR64),
+ /*8665*/ uint16(x86_xArgRM64),
+ /*8666*/ uint16(x86_xMatch),
+ /*8667*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8669*/ uint16(x86_xReadIb),
+ /*8670*/ uint16(x86_xArgAL),
+ /*8671*/ uint16(x86_xArgImm8u),
+ /*8672*/ uint16(x86_xMatch),
+ /*8673*/ uint16(x86_xCondIs64), 8676, 8692,
+ /*8676*/ uint16(x86_xCondDataSize), 8680, 8686, 0,
+ /*8680*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8682*/ uint16(x86_xReadIw),
+ /*8683*/ uint16(x86_xArgAX),
+ /*8684*/ uint16(x86_xArgImm16),
+ /*8685*/ uint16(x86_xMatch),
+ /*8686*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8688*/ uint16(x86_xReadId),
+ /*8689*/ uint16(x86_xArgEAX),
+ /*8690*/ uint16(x86_xArgImm32),
+ /*8691*/ uint16(x86_xMatch),
+ /*8692*/ uint16(x86_xCondDataSize), 8680, 8686, 8696,
+ /*8696*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*8698*/ uint16(x86_xReadId),
+ /*8699*/ uint16(x86_xArgRAX),
+ /*8700*/ uint16(x86_xArgImm32),
+ /*8701*/ uint16(x86_xMatch),
+ /*8702*/ uint16(x86_xCondIs64), 8705, 0,
+ /*8705*/ uint16(x86_xSetOp), uint16(x86_AAS),
+ /*8707*/ uint16(x86_xMatch),
+ /*8708*/ uint16(x86_xCondIs64), 8711, 0,
+ /*8711*/ uint16(x86_xCondDataSize), 8715, 8719, 0,
+ /*8715*/ uint16(x86_xSetOp), uint16(x86_INC),
+ /*8717*/ uint16(x86_xArgR16op),
+ /*8718*/ uint16(x86_xMatch),
+ /*8719*/ uint16(x86_xSetOp), uint16(x86_INC),
+ /*8721*/ uint16(x86_xArgR32op),
+ /*8722*/ uint16(x86_xMatch),
+ /*8723*/ uint16(x86_xCondIs64), 8726, 0,
+ /*8726*/ uint16(x86_xCondDataSize), 8730, 8734, 0,
+ /*8730*/ uint16(x86_xSetOp), uint16(x86_DEC),
+ /*8732*/ uint16(x86_xArgR16op),
+ /*8733*/ uint16(x86_xMatch),
+ /*8734*/ uint16(x86_xSetOp), uint16(x86_DEC),
+ /*8736*/ uint16(x86_xArgR32op),
+ /*8737*/ uint16(x86_xMatch),
+ /*8738*/ uint16(x86_xCondIs64), 8741, 8753,
+ /*8741*/ uint16(x86_xCondDataSize), 8745, 8749, 0,
+ /*8745*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8747*/ uint16(x86_xArgR16op),
+ /*8748*/ uint16(x86_xMatch),
+ /*8749*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8751*/ uint16(x86_xArgR32op),
+ /*8752*/ uint16(x86_xMatch),
+ /*8753*/ uint16(x86_xCondDataSize), 8745, 8757, 8761,
+ /*8757*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8759*/ uint16(x86_xArgR64op),
+ /*8760*/ uint16(x86_xMatch),
+ /*8761*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8763*/ uint16(x86_xArgR64op),
+ /*8764*/ uint16(x86_xMatch),
+ /*8765*/ uint16(x86_xCondIs64), 8768, 8780,
+ /*8768*/ uint16(x86_xCondDataSize), 8772, 8776, 0,
+ /*8772*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*8774*/ uint16(x86_xArgR16op),
+ /*8775*/ uint16(x86_xMatch),
+ /*8776*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*8778*/ uint16(x86_xArgR32op),
+ /*8779*/ uint16(x86_xMatch),
+ /*8780*/ uint16(x86_xCondDataSize), 8772, 8784, 8788,
+ /*8784*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*8786*/ uint16(x86_xArgR64op),
+ /*8787*/ uint16(x86_xMatch),
+ /*8788*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*8790*/ uint16(x86_xArgR64op),
+ /*8791*/ uint16(x86_xMatch),
+ /*8792*/ uint16(x86_xCondIs64), 8795, 0,
+ /*8795*/ uint16(x86_xCondDataSize), 8799, 8802, 0,
+ /*8799*/ uint16(x86_xSetOp), uint16(x86_PUSHA),
+ /*8801*/ uint16(x86_xMatch),
+ /*8802*/ uint16(x86_xSetOp), uint16(x86_PUSHAD),
+ /*8804*/ uint16(x86_xMatch),
+ /*8805*/ uint16(x86_xCondIs64), 8808, 0,
+ /*8808*/ uint16(x86_xCondDataSize), 8812, 8815, 0,
+ /*8812*/ uint16(x86_xSetOp), uint16(x86_POPA),
+ /*8814*/ uint16(x86_xMatch),
+ /*8815*/ uint16(x86_xSetOp), uint16(x86_POPAD),
+ /*8817*/ uint16(x86_xMatch),
+ /*8818*/ uint16(x86_xCondIs64), 8821, 0,
+ /*8821*/ uint16(x86_xCondDataSize), 8825, 8831, 0,
+ /*8825*/ uint16(x86_xSetOp), uint16(x86_BOUND),
+ /*8827*/ uint16(x86_xReadSlashR),
+ /*8828*/ uint16(x86_xArgR16),
+ /*8829*/ uint16(x86_xArgM16and16),
+ /*8830*/ uint16(x86_xMatch),
+ /*8831*/ uint16(x86_xSetOp), uint16(x86_BOUND),
+ /*8833*/ uint16(x86_xReadSlashR),
+ /*8834*/ uint16(x86_xArgR32),
+ /*8835*/ uint16(x86_xArgM32and32),
+ /*8836*/ uint16(x86_xMatch),
+ /*8837*/ uint16(x86_xCondIs64), 8840, 8846,
+ /*8840*/ uint16(x86_xSetOp), uint16(x86_ARPL),
+ /*8842*/ uint16(x86_xReadSlashR),
+ /*8843*/ uint16(x86_xArgRM16),
+ /*8844*/ uint16(x86_xArgR16),
+ /*8845*/ uint16(x86_xMatch),
+ /*8846*/ uint16(x86_xCondDataSize), 8850, 8856, 8862,
+ /*8850*/ uint16(x86_xSetOp), uint16(x86_MOVSXD),
+ /*8852*/ uint16(x86_xReadSlashR),
+ /*8853*/ uint16(x86_xArgR16),
+ /*8854*/ uint16(x86_xArgRM32),
+ /*8855*/ uint16(x86_xMatch),
+ /*8856*/ uint16(x86_xSetOp), uint16(x86_MOVSXD),
+ /*8858*/ uint16(x86_xReadSlashR),
+ /*8859*/ uint16(x86_xArgR32),
+ /*8860*/ uint16(x86_xArgRM32),
+ /*8861*/ uint16(x86_xMatch),
+ /*8862*/ uint16(x86_xSetOp), uint16(x86_MOVSXD),
+ /*8864*/ uint16(x86_xReadSlashR),
+ /*8865*/ uint16(x86_xArgR64),
+ /*8866*/ uint16(x86_xArgRM32),
+ /*8867*/ uint16(x86_xMatch),
+ /*8868*/ uint16(x86_xCondDataSize), 8872, 8877, 8882,
+ /*8872*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8874*/ uint16(x86_xReadIw),
+ /*8875*/ uint16(x86_xArgImm16),
+ /*8876*/ uint16(x86_xMatch),
+ /*8877*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8879*/ uint16(x86_xReadId),
+ /*8880*/ uint16(x86_xArgImm32),
+ /*8881*/ uint16(x86_xMatch),
+ /*8882*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8884*/ uint16(x86_xReadId),
+ /*8885*/ uint16(x86_xArgImm32),
+ /*8886*/ uint16(x86_xMatch),
+ /*8887*/ uint16(x86_xCondIs64), 8890, 8910,
+ /*8890*/ uint16(x86_xCondDataSize), 8894, 8902, 0,
+ /*8894*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*8896*/ uint16(x86_xReadSlashR),
+ /*8897*/ uint16(x86_xReadIw),
+ /*8898*/ uint16(x86_xArgR16),
+ /*8899*/ uint16(x86_xArgRM16),
+ /*8900*/ uint16(x86_xArgImm16),
+ /*8901*/ uint16(x86_xMatch),
+ /*8902*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*8904*/ uint16(x86_xReadSlashR),
+ /*8905*/ uint16(x86_xReadId),
+ /*8906*/ uint16(x86_xArgR32),
+ /*8907*/ uint16(x86_xArgRM32),
+ /*8908*/ uint16(x86_xArgImm32),
+ /*8909*/ uint16(x86_xMatch),
+ /*8910*/ uint16(x86_xCondDataSize), 8894, 8902, 8914,
+ /*8914*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*8916*/ uint16(x86_xReadSlashR),
+ /*8917*/ uint16(x86_xReadId),
+ /*8918*/ uint16(x86_xArgR64),
+ /*8919*/ uint16(x86_xArgRM64),
+ /*8920*/ uint16(x86_xArgImm32),
+ /*8921*/ uint16(x86_xMatch),
+ /*8922*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*8924*/ uint16(x86_xReadIb),
+ /*8925*/ uint16(x86_xArgImm8),
+ /*8926*/ uint16(x86_xMatch),
+ /*8927*/ uint16(x86_xCondIs64), 8930, 8950,
+ /*8930*/ uint16(x86_xCondDataSize), 8934, 8942, 0,
+ /*8934*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*8936*/ uint16(x86_xReadSlashR),
+ /*8937*/ uint16(x86_xReadIb),
+ /*8938*/ uint16(x86_xArgR16),
+ /*8939*/ uint16(x86_xArgRM16),
+ /*8940*/ uint16(x86_xArgImm8),
+ /*8941*/ uint16(x86_xMatch),
+ /*8942*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*8944*/ uint16(x86_xReadSlashR),
+ /*8945*/ uint16(x86_xReadIb),
+ /*8946*/ uint16(x86_xArgR32),
+ /*8947*/ uint16(x86_xArgRM32),
+ /*8948*/ uint16(x86_xArgImm8),
+ /*8949*/ uint16(x86_xMatch),
+ /*8950*/ uint16(x86_xCondDataSize), 8934, 8942, 8954,
+ /*8954*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*8956*/ uint16(x86_xReadSlashR),
+ /*8957*/ uint16(x86_xReadIb),
+ /*8958*/ uint16(x86_xArgR64),
+ /*8959*/ uint16(x86_xArgRM64),
+ /*8960*/ uint16(x86_xArgImm8),
+ /*8961*/ uint16(x86_xMatch),
+ /*8962*/ uint16(x86_xSetOp), uint16(x86_INSB),
+ /*8964*/ uint16(x86_xMatch),
+ /*8965*/ uint16(x86_xCondDataSize), 8969, 8972, 8975,
+ /*8969*/ uint16(x86_xSetOp), uint16(x86_INSW),
+ /*8971*/ uint16(x86_xMatch),
+ /*8972*/ uint16(x86_xSetOp), uint16(x86_INSD),
+ /*8974*/ uint16(x86_xMatch),
+ /*8975*/ uint16(x86_xSetOp), uint16(x86_INSD),
+ /*8977*/ uint16(x86_xMatch),
+ /*8978*/ uint16(x86_xSetOp), uint16(x86_OUTSB),
+ /*8980*/ uint16(x86_xMatch),
+ /*8981*/ uint16(x86_xCondDataSize), 8985, 8988, 8991,
+ /*8985*/ uint16(x86_xSetOp), uint16(x86_OUTSW),
+ /*8987*/ uint16(x86_xMatch),
+ /*8988*/ uint16(x86_xSetOp), uint16(x86_OUTSD),
+ /*8990*/ uint16(x86_xMatch),
+ /*8991*/ uint16(x86_xSetOp), uint16(x86_OUTSD),
+ /*8993*/ uint16(x86_xMatch),
+ /*8994*/ uint16(x86_xSetOp), uint16(x86_JO),
+ /*8996*/ uint16(x86_xReadCb),
+ /*8997*/ uint16(x86_xArgRel8),
+ /*8998*/ uint16(x86_xMatch),
+ /*8999*/ uint16(x86_xSetOp), uint16(x86_JNO),
+ /*9001*/ uint16(x86_xReadCb),
+ /*9002*/ uint16(x86_xArgRel8),
+ /*9003*/ uint16(x86_xMatch),
+ /*9004*/ uint16(x86_xSetOp), uint16(x86_JB),
+ /*9006*/ uint16(x86_xReadCb),
+ /*9007*/ uint16(x86_xArgRel8),
+ /*9008*/ uint16(x86_xMatch),
+ /*9009*/ uint16(x86_xSetOp), uint16(x86_JAE),
+ /*9011*/ uint16(x86_xReadCb),
+ /*9012*/ uint16(x86_xArgRel8),
+ /*9013*/ uint16(x86_xMatch),
+ /*9014*/ uint16(x86_xSetOp), uint16(x86_JE),
+ /*9016*/ uint16(x86_xReadCb),
+ /*9017*/ uint16(x86_xArgRel8),
+ /*9018*/ uint16(x86_xMatch),
+ /*9019*/ uint16(x86_xSetOp), uint16(x86_JNE),
+ /*9021*/ uint16(x86_xReadCb),
+ /*9022*/ uint16(x86_xArgRel8),
+ /*9023*/ uint16(x86_xMatch),
+ /*9024*/ uint16(x86_xSetOp), uint16(x86_JBE),
+ /*9026*/ uint16(x86_xReadCb),
+ /*9027*/ uint16(x86_xArgRel8),
+ /*9028*/ uint16(x86_xMatch),
+ /*9029*/ uint16(x86_xSetOp), uint16(x86_JA),
+ /*9031*/ uint16(x86_xReadCb),
+ /*9032*/ uint16(x86_xArgRel8),
+ /*9033*/ uint16(x86_xMatch),
+ /*9034*/ uint16(x86_xSetOp), uint16(x86_JS),
+ /*9036*/ uint16(x86_xReadCb),
+ /*9037*/ uint16(x86_xArgRel8),
+ /*9038*/ uint16(x86_xMatch),
+ /*9039*/ uint16(x86_xSetOp), uint16(x86_JNS),
+ /*9041*/ uint16(x86_xReadCb),
+ /*9042*/ uint16(x86_xArgRel8),
+ /*9043*/ uint16(x86_xMatch),
+ /*9044*/ uint16(x86_xSetOp), uint16(x86_JP),
+ /*9046*/ uint16(x86_xReadCb),
+ /*9047*/ uint16(x86_xArgRel8),
+ /*9048*/ uint16(x86_xMatch),
+ /*9049*/ uint16(x86_xSetOp), uint16(x86_JNP),
+ /*9051*/ uint16(x86_xReadCb),
+ /*9052*/ uint16(x86_xArgRel8),
+ /*9053*/ uint16(x86_xMatch),
+ /*9054*/ uint16(x86_xSetOp), uint16(x86_JL),
+ /*9056*/ uint16(x86_xReadCb),
+ /*9057*/ uint16(x86_xArgRel8),
+ /*9058*/ uint16(x86_xMatch),
+ /*9059*/ uint16(x86_xSetOp), uint16(x86_JGE),
+ /*9061*/ uint16(x86_xReadCb),
+ /*9062*/ uint16(x86_xArgRel8),
+ /*9063*/ uint16(x86_xMatch),
+ /*9064*/ uint16(x86_xSetOp), uint16(x86_JLE),
+ /*9066*/ uint16(x86_xReadCb),
+ /*9067*/ uint16(x86_xArgRel8),
+ /*9068*/ uint16(x86_xMatch),
+ /*9069*/ uint16(x86_xSetOp), uint16(x86_JG),
+ /*9071*/ uint16(x86_xReadCb),
+ /*9072*/ uint16(x86_xArgRel8),
+ /*9073*/ uint16(x86_xMatch),
+ /*9074*/ uint16(x86_xCondSlashR),
+ 9083, // 0
+ 9089, // 1
+ 9095, // 2
+ 9101, // 3
+ 9107, // 4
+ 9113, // 5
+ 9119, // 6
+ 9125, // 7
+ /*9083*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9085*/ uint16(x86_xReadIb),
+ /*9086*/ uint16(x86_xArgRM8),
+ /*9087*/ uint16(x86_xArgImm8u),
+ /*9088*/ uint16(x86_xMatch),
+ /*9089*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9091*/ uint16(x86_xReadIb),
+ /*9092*/ uint16(x86_xArgRM8),
+ /*9093*/ uint16(x86_xArgImm8u),
+ /*9094*/ uint16(x86_xMatch),
+ /*9095*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9097*/ uint16(x86_xReadIb),
+ /*9098*/ uint16(x86_xArgRM8),
+ /*9099*/ uint16(x86_xArgImm8u),
+ /*9100*/ uint16(x86_xMatch),
+ /*9101*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9103*/ uint16(x86_xReadIb),
+ /*9104*/ uint16(x86_xArgRM8),
+ /*9105*/ uint16(x86_xArgImm8u),
+ /*9106*/ uint16(x86_xMatch),
+ /*9107*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9109*/ uint16(x86_xReadIb),
+ /*9110*/ uint16(x86_xArgRM8),
+ /*9111*/ uint16(x86_xArgImm8u),
+ /*9112*/ uint16(x86_xMatch),
+ /*9113*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9115*/ uint16(x86_xReadIb),
+ /*9116*/ uint16(x86_xArgRM8),
+ /*9117*/ uint16(x86_xArgImm8u),
+ /*9118*/ uint16(x86_xMatch),
+ /*9119*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9121*/ uint16(x86_xReadIb),
+ /*9122*/ uint16(x86_xArgRM8),
+ /*9123*/ uint16(x86_xArgImm8u),
+ /*9124*/ uint16(x86_xMatch),
+ /*9125*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9127*/ uint16(x86_xReadIb),
+ /*9128*/ uint16(x86_xArgRM8),
+ /*9129*/ uint16(x86_xArgImm8u),
+ /*9130*/ uint16(x86_xMatch),
+ /*9131*/ uint16(x86_xCondSlashR),
+ 9140, // 0
+ 9169, // 1
+ 9198, // 2
+ 9227, // 3
+ 9256, // 4
+ 9285, // 5
+ 9314, // 6
+ 9343, // 7
+ /*9140*/ uint16(x86_xCondIs64), 9143, 9159,
+ /*9143*/ uint16(x86_xCondDataSize), 9147, 9153, 0,
+ /*9147*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9149*/ uint16(x86_xReadIw),
+ /*9150*/ uint16(x86_xArgRM16),
+ /*9151*/ uint16(x86_xArgImm16),
+ /*9152*/ uint16(x86_xMatch),
+ /*9153*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9155*/ uint16(x86_xReadId),
+ /*9156*/ uint16(x86_xArgRM32),
+ /*9157*/ uint16(x86_xArgImm32),
+ /*9158*/ uint16(x86_xMatch),
+ /*9159*/ uint16(x86_xCondDataSize), 9147, 9153, 9163,
+ /*9163*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9165*/ uint16(x86_xReadId),
+ /*9166*/ uint16(x86_xArgRM64),
+ /*9167*/ uint16(x86_xArgImm32),
+ /*9168*/ uint16(x86_xMatch),
+ /*9169*/ uint16(x86_xCondIs64), 9172, 9188,
+ /*9172*/ uint16(x86_xCondDataSize), 9176, 9182, 0,
+ /*9176*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9178*/ uint16(x86_xReadIw),
+ /*9179*/ uint16(x86_xArgRM16),
+ /*9180*/ uint16(x86_xArgImm16),
+ /*9181*/ uint16(x86_xMatch),
+ /*9182*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9184*/ uint16(x86_xReadId),
+ /*9185*/ uint16(x86_xArgRM32),
+ /*9186*/ uint16(x86_xArgImm32),
+ /*9187*/ uint16(x86_xMatch),
+ /*9188*/ uint16(x86_xCondDataSize), 9176, 9182, 9192,
+ /*9192*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9194*/ uint16(x86_xReadId),
+ /*9195*/ uint16(x86_xArgRM64),
+ /*9196*/ uint16(x86_xArgImm32),
+ /*9197*/ uint16(x86_xMatch),
+ /*9198*/ uint16(x86_xCondIs64), 9201, 9217,
+ /*9201*/ uint16(x86_xCondDataSize), 9205, 9211, 0,
+ /*9205*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9207*/ uint16(x86_xReadIw),
+ /*9208*/ uint16(x86_xArgRM16),
+ /*9209*/ uint16(x86_xArgImm16),
+ /*9210*/ uint16(x86_xMatch),
+ /*9211*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9213*/ uint16(x86_xReadId),
+ /*9214*/ uint16(x86_xArgRM32),
+ /*9215*/ uint16(x86_xArgImm32),
+ /*9216*/ uint16(x86_xMatch),
+ /*9217*/ uint16(x86_xCondDataSize), 9205, 9211, 9221,
+ /*9221*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9223*/ uint16(x86_xReadId),
+ /*9224*/ uint16(x86_xArgRM64),
+ /*9225*/ uint16(x86_xArgImm32),
+ /*9226*/ uint16(x86_xMatch),
+ /*9227*/ uint16(x86_xCondIs64), 9230, 9246,
+ /*9230*/ uint16(x86_xCondDataSize), 9234, 9240, 0,
+ /*9234*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9236*/ uint16(x86_xReadIw),
+ /*9237*/ uint16(x86_xArgRM16),
+ /*9238*/ uint16(x86_xArgImm16),
+ /*9239*/ uint16(x86_xMatch),
+ /*9240*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9242*/ uint16(x86_xReadId),
+ /*9243*/ uint16(x86_xArgRM32),
+ /*9244*/ uint16(x86_xArgImm32),
+ /*9245*/ uint16(x86_xMatch),
+ /*9246*/ uint16(x86_xCondDataSize), 9234, 9240, 9250,
+ /*9250*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9252*/ uint16(x86_xReadId),
+ /*9253*/ uint16(x86_xArgRM64),
+ /*9254*/ uint16(x86_xArgImm32),
+ /*9255*/ uint16(x86_xMatch),
+ /*9256*/ uint16(x86_xCondIs64), 9259, 9275,
+ /*9259*/ uint16(x86_xCondDataSize), 9263, 9269, 0,
+ /*9263*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9265*/ uint16(x86_xReadIw),
+ /*9266*/ uint16(x86_xArgRM16),
+ /*9267*/ uint16(x86_xArgImm16),
+ /*9268*/ uint16(x86_xMatch),
+ /*9269*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9271*/ uint16(x86_xReadId),
+ /*9272*/ uint16(x86_xArgRM32),
+ /*9273*/ uint16(x86_xArgImm32),
+ /*9274*/ uint16(x86_xMatch),
+ /*9275*/ uint16(x86_xCondDataSize), 9263, 9269, 9279,
+ /*9279*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9281*/ uint16(x86_xReadId),
+ /*9282*/ uint16(x86_xArgRM64),
+ /*9283*/ uint16(x86_xArgImm32),
+ /*9284*/ uint16(x86_xMatch),
+ /*9285*/ uint16(x86_xCondIs64), 9288, 9304,
+ /*9288*/ uint16(x86_xCondDataSize), 9292, 9298, 0,
+ /*9292*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9294*/ uint16(x86_xReadIw),
+ /*9295*/ uint16(x86_xArgRM16),
+ /*9296*/ uint16(x86_xArgImm16),
+ /*9297*/ uint16(x86_xMatch),
+ /*9298*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9300*/ uint16(x86_xReadId),
+ /*9301*/ uint16(x86_xArgRM32),
+ /*9302*/ uint16(x86_xArgImm32),
+ /*9303*/ uint16(x86_xMatch),
+ /*9304*/ uint16(x86_xCondDataSize), 9292, 9298, 9308,
+ /*9308*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9310*/ uint16(x86_xReadId),
+ /*9311*/ uint16(x86_xArgRM64),
+ /*9312*/ uint16(x86_xArgImm32),
+ /*9313*/ uint16(x86_xMatch),
+ /*9314*/ uint16(x86_xCondIs64), 9317, 9333,
+ /*9317*/ uint16(x86_xCondDataSize), 9321, 9327, 0,
+ /*9321*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9323*/ uint16(x86_xReadIw),
+ /*9324*/ uint16(x86_xArgRM16),
+ /*9325*/ uint16(x86_xArgImm16),
+ /*9326*/ uint16(x86_xMatch),
+ /*9327*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9329*/ uint16(x86_xReadId),
+ /*9330*/ uint16(x86_xArgRM32),
+ /*9331*/ uint16(x86_xArgImm32),
+ /*9332*/ uint16(x86_xMatch),
+ /*9333*/ uint16(x86_xCondDataSize), 9321, 9327, 9337,
+ /*9337*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9339*/ uint16(x86_xReadId),
+ /*9340*/ uint16(x86_xArgRM64),
+ /*9341*/ uint16(x86_xArgImm32),
+ /*9342*/ uint16(x86_xMatch),
+ /*9343*/ uint16(x86_xCondIs64), 9346, 9362,
+ /*9346*/ uint16(x86_xCondDataSize), 9350, 9356, 0,
+ /*9350*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9352*/ uint16(x86_xReadIw),
+ /*9353*/ uint16(x86_xArgRM16),
+ /*9354*/ uint16(x86_xArgImm16),
+ /*9355*/ uint16(x86_xMatch),
+ /*9356*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9358*/ uint16(x86_xReadId),
+ /*9359*/ uint16(x86_xArgRM32),
+ /*9360*/ uint16(x86_xArgImm32),
+ /*9361*/ uint16(x86_xMatch),
+ /*9362*/ uint16(x86_xCondDataSize), 9350, 9356, 9366,
+ /*9366*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9368*/ uint16(x86_xReadId),
+ /*9369*/ uint16(x86_xArgRM64),
+ /*9370*/ uint16(x86_xArgImm32),
+ /*9371*/ uint16(x86_xMatch),
+ /*9372*/ uint16(x86_xCondSlashR),
+ 9381, // 0
+ 9410, // 1
+ 9439, // 2
+ 9468, // 3
+ 9497, // 4
+ 9526, // 5
+ 9555, // 6
+ 9584, // 7
+ /*9381*/ uint16(x86_xCondIs64), 9384, 9400,
+ /*9384*/ uint16(x86_xCondDataSize), 9388, 9394, 0,
+ /*9388*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9390*/ uint16(x86_xReadIb),
+ /*9391*/ uint16(x86_xArgRM16),
+ /*9392*/ uint16(x86_xArgImm8),
+ /*9393*/ uint16(x86_xMatch),
+ /*9394*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9396*/ uint16(x86_xReadIb),
+ /*9397*/ uint16(x86_xArgRM32),
+ /*9398*/ uint16(x86_xArgImm8),
+ /*9399*/ uint16(x86_xMatch),
+ /*9400*/ uint16(x86_xCondDataSize), 9388, 9394, 9404,
+ /*9404*/ uint16(x86_xSetOp), uint16(x86_ADD),
+ /*9406*/ uint16(x86_xReadIb),
+ /*9407*/ uint16(x86_xArgRM64),
+ /*9408*/ uint16(x86_xArgImm8),
+ /*9409*/ uint16(x86_xMatch),
+ /*9410*/ uint16(x86_xCondIs64), 9413, 9429,
+ /*9413*/ uint16(x86_xCondDataSize), 9417, 9423, 0,
+ /*9417*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9419*/ uint16(x86_xReadIb),
+ /*9420*/ uint16(x86_xArgRM16),
+ /*9421*/ uint16(x86_xArgImm8),
+ /*9422*/ uint16(x86_xMatch),
+ /*9423*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9425*/ uint16(x86_xReadIb),
+ /*9426*/ uint16(x86_xArgRM32),
+ /*9427*/ uint16(x86_xArgImm8),
+ /*9428*/ uint16(x86_xMatch),
+ /*9429*/ uint16(x86_xCondDataSize), 9417, 9423, 9433,
+ /*9433*/ uint16(x86_xSetOp), uint16(x86_OR),
+ /*9435*/ uint16(x86_xReadIb),
+ /*9436*/ uint16(x86_xArgRM64),
+ /*9437*/ uint16(x86_xArgImm8),
+ /*9438*/ uint16(x86_xMatch),
+ /*9439*/ uint16(x86_xCondIs64), 9442, 9458,
+ /*9442*/ uint16(x86_xCondDataSize), 9446, 9452, 0,
+ /*9446*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9448*/ uint16(x86_xReadIb),
+ /*9449*/ uint16(x86_xArgRM16),
+ /*9450*/ uint16(x86_xArgImm8),
+ /*9451*/ uint16(x86_xMatch),
+ /*9452*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9454*/ uint16(x86_xReadIb),
+ /*9455*/ uint16(x86_xArgRM32),
+ /*9456*/ uint16(x86_xArgImm8),
+ /*9457*/ uint16(x86_xMatch),
+ /*9458*/ uint16(x86_xCondDataSize), 9446, 9452, 9462,
+ /*9462*/ uint16(x86_xSetOp), uint16(x86_ADC),
+ /*9464*/ uint16(x86_xReadIb),
+ /*9465*/ uint16(x86_xArgRM64),
+ /*9466*/ uint16(x86_xArgImm8),
+ /*9467*/ uint16(x86_xMatch),
+ /*9468*/ uint16(x86_xCondIs64), 9471, 9487,
+ /*9471*/ uint16(x86_xCondDataSize), 9475, 9481, 0,
+ /*9475*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9477*/ uint16(x86_xReadIb),
+ /*9478*/ uint16(x86_xArgRM16),
+ /*9479*/ uint16(x86_xArgImm8),
+ /*9480*/ uint16(x86_xMatch),
+ /*9481*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9483*/ uint16(x86_xReadIb),
+ /*9484*/ uint16(x86_xArgRM32),
+ /*9485*/ uint16(x86_xArgImm8),
+ /*9486*/ uint16(x86_xMatch),
+ /*9487*/ uint16(x86_xCondDataSize), 9475, 9481, 9491,
+ /*9491*/ uint16(x86_xSetOp), uint16(x86_SBB),
+ /*9493*/ uint16(x86_xReadIb),
+ /*9494*/ uint16(x86_xArgRM64),
+ /*9495*/ uint16(x86_xArgImm8),
+ /*9496*/ uint16(x86_xMatch),
+ /*9497*/ uint16(x86_xCondIs64), 9500, 9516,
+ /*9500*/ uint16(x86_xCondDataSize), 9504, 9510, 0,
+ /*9504*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9506*/ uint16(x86_xReadIb),
+ /*9507*/ uint16(x86_xArgRM16),
+ /*9508*/ uint16(x86_xArgImm8),
+ /*9509*/ uint16(x86_xMatch),
+ /*9510*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9512*/ uint16(x86_xReadIb),
+ /*9513*/ uint16(x86_xArgRM32),
+ /*9514*/ uint16(x86_xArgImm8),
+ /*9515*/ uint16(x86_xMatch),
+ /*9516*/ uint16(x86_xCondDataSize), 9504, 9510, 9520,
+ /*9520*/ uint16(x86_xSetOp), uint16(x86_AND),
+ /*9522*/ uint16(x86_xReadIb),
+ /*9523*/ uint16(x86_xArgRM64),
+ /*9524*/ uint16(x86_xArgImm8),
+ /*9525*/ uint16(x86_xMatch),
+ /*9526*/ uint16(x86_xCondIs64), 9529, 9545,
+ /*9529*/ uint16(x86_xCondDataSize), 9533, 9539, 0,
+ /*9533*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9535*/ uint16(x86_xReadIb),
+ /*9536*/ uint16(x86_xArgRM16),
+ /*9537*/ uint16(x86_xArgImm8),
+ /*9538*/ uint16(x86_xMatch),
+ /*9539*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9541*/ uint16(x86_xReadIb),
+ /*9542*/ uint16(x86_xArgRM32),
+ /*9543*/ uint16(x86_xArgImm8),
+ /*9544*/ uint16(x86_xMatch),
+ /*9545*/ uint16(x86_xCondDataSize), 9533, 9539, 9549,
+ /*9549*/ uint16(x86_xSetOp), uint16(x86_SUB),
+ /*9551*/ uint16(x86_xReadIb),
+ /*9552*/ uint16(x86_xArgRM64),
+ /*9553*/ uint16(x86_xArgImm8),
+ /*9554*/ uint16(x86_xMatch),
+ /*9555*/ uint16(x86_xCondIs64), 9558, 9574,
+ /*9558*/ uint16(x86_xCondDataSize), 9562, 9568, 0,
+ /*9562*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9564*/ uint16(x86_xReadIb),
+ /*9565*/ uint16(x86_xArgRM16),
+ /*9566*/ uint16(x86_xArgImm8),
+ /*9567*/ uint16(x86_xMatch),
+ /*9568*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9570*/ uint16(x86_xReadIb),
+ /*9571*/ uint16(x86_xArgRM32),
+ /*9572*/ uint16(x86_xArgImm8),
+ /*9573*/ uint16(x86_xMatch),
+ /*9574*/ uint16(x86_xCondDataSize), 9562, 9568, 9578,
+ /*9578*/ uint16(x86_xSetOp), uint16(x86_XOR),
+ /*9580*/ uint16(x86_xReadIb),
+ /*9581*/ uint16(x86_xArgRM64),
+ /*9582*/ uint16(x86_xArgImm8),
+ /*9583*/ uint16(x86_xMatch),
+ /*9584*/ uint16(x86_xCondIs64), 9587, 9603,
+ /*9587*/ uint16(x86_xCondDataSize), 9591, 9597, 0,
+ /*9591*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9593*/ uint16(x86_xReadIb),
+ /*9594*/ uint16(x86_xArgRM16),
+ /*9595*/ uint16(x86_xArgImm8),
+ /*9596*/ uint16(x86_xMatch),
+ /*9597*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9599*/ uint16(x86_xReadIb),
+ /*9600*/ uint16(x86_xArgRM32),
+ /*9601*/ uint16(x86_xArgImm8),
+ /*9602*/ uint16(x86_xMatch),
+ /*9603*/ uint16(x86_xCondDataSize), 9591, 9597, 9607,
+ /*9607*/ uint16(x86_xSetOp), uint16(x86_CMP),
+ /*9609*/ uint16(x86_xReadIb),
+ /*9610*/ uint16(x86_xArgRM64),
+ /*9611*/ uint16(x86_xArgImm8),
+ /*9612*/ uint16(x86_xMatch),
+ /*9613*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*9615*/ uint16(x86_xReadSlashR),
+ /*9616*/ uint16(x86_xArgRM8),
+ /*9617*/ uint16(x86_xArgR8),
+ /*9618*/ uint16(x86_xMatch),
+ /*9619*/ uint16(x86_xCondIs64), 9622, 9638,
+ /*9622*/ uint16(x86_xCondDataSize), 9626, 9632, 0,
+ /*9626*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*9628*/ uint16(x86_xReadSlashR),
+ /*9629*/ uint16(x86_xArgRM16),
+ /*9630*/ uint16(x86_xArgR16),
+ /*9631*/ uint16(x86_xMatch),
+ /*9632*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*9634*/ uint16(x86_xReadSlashR),
+ /*9635*/ uint16(x86_xArgRM32),
+ /*9636*/ uint16(x86_xArgR32),
+ /*9637*/ uint16(x86_xMatch),
+ /*9638*/ uint16(x86_xCondDataSize), 9626, 9632, 9642,
+ /*9642*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*9644*/ uint16(x86_xReadSlashR),
+ /*9645*/ uint16(x86_xArgRM64),
+ /*9646*/ uint16(x86_xArgR64),
+ /*9647*/ uint16(x86_xMatch),
+ /*9648*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9650*/ uint16(x86_xReadSlashR),
+ /*9651*/ uint16(x86_xArgRM8),
+ /*9652*/ uint16(x86_xArgR8),
+ /*9653*/ uint16(x86_xMatch),
+ /*9654*/ uint16(x86_xCondIs64), 9657, 9673,
+ /*9657*/ uint16(x86_xCondDataSize), 9661, 9667, 0,
+ /*9661*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9663*/ uint16(x86_xReadSlashR),
+ /*9664*/ uint16(x86_xArgRM16),
+ /*9665*/ uint16(x86_xArgR16),
+ /*9666*/ uint16(x86_xMatch),
+ /*9667*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9669*/ uint16(x86_xReadSlashR),
+ /*9670*/ uint16(x86_xArgRM32),
+ /*9671*/ uint16(x86_xArgR32),
+ /*9672*/ uint16(x86_xMatch),
+ /*9673*/ uint16(x86_xCondDataSize), 9661, 9667, 9677,
+ /*9677*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9679*/ uint16(x86_xReadSlashR),
+ /*9680*/ uint16(x86_xArgRM64),
+ /*9681*/ uint16(x86_xArgR64),
+ /*9682*/ uint16(x86_xMatch),
+ /*9683*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9685*/ uint16(x86_xReadSlashR),
+ /*9686*/ uint16(x86_xArgRM8),
+ /*9687*/ uint16(x86_xArgR8),
+ /*9688*/ uint16(x86_xMatch),
+ /*9689*/ uint16(x86_xCondDataSize), 9693, 9699, 9705,
+ /*9693*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9695*/ uint16(x86_xReadSlashR),
+ /*9696*/ uint16(x86_xArgRM16),
+ /*9697*/ uint16(x86_xArgR16),
+ /*9698*/ uint16(x86_xMatch),
+ /*9699*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9701*/ uint16(x86_xReadSlashR),
+ /*9702*/ uint16(x86_xArgRM32),
+ /*9703*/ uint16(x86_xArgR32),
+ /*9704*/ uint16(x86_xMatch),
+ /*9705*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9707*/ uint16(x86_xReadSlashR),
+ /*9708*/ uint16(x86_xArgRM64),
+ /*9709*/ uint16(x86_xArgR64),
+ /*9710*/ uint16(x86_xMatch),
+ /*9711*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9713*/ uint16(x86_xReadSlashR),
+ /*9714*/ uint16(x86_xArgR8),
+ /*9715*/ uint16(x86_xArgRM8),
+ /*9716*/ uint16(x86_xMatch),
+ /*9717*/ uint16(x86_xCondDataSize), 9721, 9727, 9733,
+ /*9721*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9723*/ uint16(x86_xReadSlashR),
+ /*9724*/ uint16(x86_xArgR16),
+ /*9725*/ uint16(x86_xArgRM16),
+ /*9726*/ uint16(x86_xMatch),
+ /*9727*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9729*/ uint16(x86_xReadSlashR),
+ /*9730*/ uint16(x86_xArgR32),
+ /*9731*/ uint16(x86_xArgRM32),
+ /*9732*/ uint16(x86_xMatch),
+ /*9733*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9735*/ uint16(x86_xReadSlashR),
+ /*9736*/ uint16(x86_xArgR64),
+ /*9737*/ uint16(x86_xArgRM64),
+ /*9738*/ uint16(x86_xMatch),
+ /*9739*/ uint16(x86_xCondIs64), 9742, 9758,
+ /*9742*/ uint16(x86_xCondDataSize), 9746, 9752, 0,
+ /*9746*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9748*/ uint16(x86_xReadSlashR),
+ /*9749*/ uint16(x86_xArgRM16),
+ /*9750*/ uint16(x86_xArgSreg),
+ /*9751*/ uint16(x86_xMatch),
+ /*9752*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9754*/ uint16(x86_xReadSlashR),
+ /*9755*/ uint16(x86_xArgR32M16),
+ /*9756*/ uint16(x86_xArgSreg),
+ /*9757*/ uint16(x86_xMatch),
+ /*9758*/ uint16(x86_xCondDataSize), 9746, 9752, 9762,
+ /*9762*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9764*/ uint16(x86_xReadSlashR),
+ /*9765*/ uint16(x86_xArgR64M16),
+ /*9766*/ uint16(x86_xArgSreg),
+ /*9767*/ uint16(x86_xMatch),
+ /*9768*/ uint16(x86_xCondIs64), 9771, 9787,
+ /*9771*/ uint16(x86_xCondDataSize), 9775, 9781, 0,
+ /*9775*/ uint16(x86_xSetOp), uint16(x86_LEA),
+ /*9777*/ uint16(x86_xReadSlashR),
+ /*9778*/ uint16(x86_xArgR16),
+ /*9779*/ uint16(x86_xArgM),
+ /*9780*/ uint16(x86_xMatch),
+ /*9781*/ uint16(x86_xSetOp), uint16(x86_LEA),
+ /*9783*/ uint16(x86_xReadSlashR),
+ /*9784*/ uint16(x86_xArgR32),
+ /*9785*/ uint16(x86_xArgM),
+ /*9786*/ uint16(x86_xMatch),
+ /*9787*/ uint16(x86_xCondDataSize), 9775, 9781, 9791,
+ /*9791*/ uint16(x86_xSetOp), uint16(x86_LEA),
+ /*9793*/ uint16(x86_xReadSlashR),
+ /*9794*/ uint16(x86_xArgR64),
+ /*9795*/ uint16(x86_xArgM),
+ /*9796*/ uint16(x86_xMatch),
+ /*9797*/ uint16(x86_xCondIs64), 9800, 9816,
+ /*9800*/ uint16(x86_xCondDataSize), 9804, 9810, 0,
+ /*9804*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9806*/ uint16(x86_xReadSlashR),
+ /*9807*/ uint16(x86_xArgSreg),
+ /*9808*/ uint16(x86_xArgRM16),
+ /*9809*/ uint16(x86_xMatch),
+ /*9810*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9812*/ uint16(x86_xReadSlashR),
+ /*9813*/ uint16(x86_xArgSreg),
+ /*9814*/ uint16(x86_xArgR32M16),
+ /*9815*/ uint16(x86_xMatch),
+ /*9816*/ uint16(x86_xCondDataSize), 9804, 9810, 9820,
+ /*9820*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*9822*/ uint16(x86_xReadSlashR),
+ /*9823*/ uint16(x86_xArgSreg),
+ /*9824*/ uint16(x86_xArgR64M16),
+ /*9825*/ uint16(x86_xMatch),
+ /*9826*/ uint16(x86_xCondSlashR),
+ 9835, // 0
+ 0, // 1
+ 0, // 2
+ 0, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*9835*/ uint16(x86_xCondIs64), 9838, 9850,
+ /*9838*/ uint16(x86_xCondDataSize), 9842, 9846, 0,
+ /*9842*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*9844*/ uint16(x86_xArgRM16),
+ /*9845*/ uint16(x86_xMatch),
+ /*9846*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*9848*/ uint16(x86_xArgRM32),
+ /*9849*/ uint16(x86_xMatch),
+ /*9850*/ uint16(x86_xCondDataSize), 9842, 9854, 9858,
+ /*9854*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*9856*/ uint16(x86_xArgRM64),
+ /*9857*/ uint16(x86_xMatch),
+ /*9858*/ uint16(x86_xSetOp), uint16(x86_POP),
+ /*9860*/ uint16(x86_xArgRM64),
+ /*9861*/ uint16(x86_xMatch),
+ /*9862*/ uint16(x86_xCondIs64), 9865, 9879,
+ /*9865*/ uint16(x86_xCondDataSize), 9869, 9874, 0,
+ /*9869*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9871*/ uint16(x86_xArgR16op),
+ /*9872*/ uint16(x86_xArgAX),
+ /*9873*/ uint16(x86_xMatch),
+ /*9874*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9876*/ uint16(x86_xArgR32op),
+ /*9877*/ uint16(x86_xArgEAX),
+ /*9878*/ uint16(x86_xMatch),
+ /*9879*/ uint16(x86_xCondDataSize), 9869, 9874, 9883,
+ /*9883*/ uint16(x86_xSetOp), uint16(x86_XCHG),
+ /*9885*/ uint16(x86_xArgR64op),
+ /*9886*/ uint16(x86_xArgRAX),
+ /*9887*/ uint16(x86_xMatch),
+ /*9888*/ uint16(x86_xCondIs64), 9891, 9901,
+ /*9891*/ uint16(x86_xCondDataSize), 9895, 9898, 0,
+ /*9895*/ uint16(x86_xSetOp), uint16(x86_CBW),
+ /*9897*/ uint16(x86_xMatch),
+ /*9898*/ uint16(x86_xSetOp), uint16(x86_CWDE),
+ /*9900*/ uint16(x86_xMatch),
+ /*9901*/ uint16(x86_xCondDataSize), 9895, 9898, 9905,
+ /*9905*/ uint16(x86_xSetOp), uint16(x86_CDQE),
+ /*9907*/ uint16(x86_xMatch),
+ /*9908*/ uint16(x86_xCondIs64), 9911, 9921,
+ /*9911*/ uint16(x86_xCondDataSize), 9915, 9918, 0,
+ /*9915*/ uint16(x86_xSetOp), uint16(x86_CWD),
+ /*9917*/ uint16(x86_xMatch),
+ /*9918*/ uint16(x86_xSetOp), uint16(x86_CDQ),
+ /*9920*/ uint16(x86_xMatch),
+ /*9921*/ uint16(x86_xCondDataSize), 9915, 9918, 9925,
+ /*9925*/ uint16(x86_xSetOp), uint16(x86_CQO),
+ /*9927*/ uint16(x86_xMatch),
+ /*9928*/ uint16(x86_xCondIs64), 9931, 0,
+ /*9931*/ uint16(x86_xCondDataSize), 9935, 9940, 0,
+ /*9935*/ uint16(x86_xSetOp), uint16(x86_LCALL),
+ /*9937*/ uint16(x86_xReadCd),
+ /*9938*/ uint16(x86_xArgPtr16colon16),
+ /*9939*/ uint16(x86_xMatch),
+ /*9940*/ uint16(x86_xSetOp), uint16(x86_LCALL),
+ /*9942*/ uint16(x86_xReadCp),
+ /*9943*/ uint16(x86_xArgPtr16colon32),
+ /*9944*/ uint16(x86_xMatch),
+ /*9945*/ uint16(x86_xSetOp), uint16(x86_FWAIT),
+ /*9947*/ uint16(x86_xMatch),
+ /*9948*/ uint16(x86_xCondIs64), 9951, 9961,
+ /*9951*/ uint16(x86_xCondDataSize), 9955, 9958, 0,
+ /*9955*/ uint16(x86_xSetOp), uint16(x86_PUSHF),
+ /*9957*/ uint16(x86_xMatch),
+ /*9958*/ uint16(x86_xSetOp), uint16(x86_PUSHFD),
+ /*9960*/ uint16(x86_xMatch),
+ /*9961*/ uint16(x86_xCondDataSize), 9955, 9965, 9968,
+ /*9965*/ uint16(x86_xSetOp), uint16(x86_PUSHFQ),
+ /*9967*/ uint16(x86_xMatch),
+ /*9968*/ uint16(x86_xSetOp), uint16(x86_PUSHFQ),
+ /*9970*/ uint16(x86_xMatch),
+ /*9971*/ uint16(x86_xCondIs64), 9974, 9984,
+ /*9974*/ uint16(x86_xCondDataSize), 9978, 9981, 0,
+ /*9978*/ uint16(x86_xSetOp), uint16(x86_POPF),
+ /*9980*/ uint16(x86_xMatch),
+ /*9981*/ uint16(x86_xSetOp), uint16(x86_POPFD),
+ /*9983*/ uint16(x86_xMatch),
+ /*9984*/ uint16(x86_xCondDataSize), 9978, 9988, 9991,
+ /*9988*/ uint16(x86_xSetOp), uint16(x86_POPFQ),
+ /*9990*/ uint16(x86_xMatch),
+ /*9991*/ uint16(x86_xSetOp), uint16(x86_POPFQ),
+ /*9993*/ uint16(x86_xMatch),
+ /*9994*/ uint16(x86_xSetOp), uint16(x86_SAHF),
+ /*9996*/ uint16(x86_xMatch),
+ /*9997*/ uint16(x86_xSetOp), uint16(x86_LAHF),
+ /*9999*/ uint16(x86_xMatch),
+ /*10000*/ uint16(x86_xCondIs64), 10003, 10009,
+ /*10003*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10005*/ uint16(x86_xReadCm),
+ /*10006*/ uint16(x86_xArgAL),
+ /*10007*/ uint16(x86_xArgMoffs8),
+ /*10008*/ uint16(x86_xMatch),
+ /*10009*/ uint16(x86_xCondDataSize), 10003, 10003, 10013,
+ /*10013*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10015*/ uint16(x86_xReadCm),
+ /*10016*/ uint16(x86_xArgAL),
+ /*10017*/ uint16(x86_xArgMoffs8),
+ /*10018*/ uint16(x86_xMatch),
+ /*10019*/ uint16(x86_xCondDataSize), 10023, 10029, 10035,
+ /*10023*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10025*/ uint16(x86_xReadCm),
+ /*10026*/ uint16(x86_xArgAX),
+ /*10027*/ uint16(x86_xArgMoffs16),
+ /*10028*/ uint16(x86_xMatch),
+ /*10029*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10031*/ uint16(x86_xReadCm),
+ /*10032*/ uint16(x86_xArgEAX),
+ /*10033*/ uint16(x86_xArgMoffs32),
+ /*10034*/ uint16(x86_xMatch),
+ /*10035*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10037*/ uint16(x86_xReadCm),
+ /*10038*/ uint16(x86_xArgRAX),
+ /*10039*/ uint16(x86_xArgMoffs64),
+ /*10040*/ uint16(x86_xMatch),
+ /*10041*/ uint16(x86_xCondIs64), 10044, 10050,
+ /*10044*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10046*/ uint16(x86_xReadCm),
+ /*10047*/ uint16(x86_xArgMoffs8),
+ /*10048*/ uint16(x86_xArgAL),
+ /*10049*/ uint16(x86_xMatch),
+ /*10050*/ uint16(x86_xCondDataSize), 10044, 10044, 10054,
+ /*10054*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10056*/ uint16(x86_xReadCm),
+ /*10057*/ uint16(x86_xArgMoffs8),
+ /*10058*/ uint16(x86_xArgAL),
+ /*10059*/ uint16(x86_xMatch),
+ /*10060*/ uint16(x86_xCondDataSize), 10064, 10070, 10076,
+ /*10064*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10066*/ uint16(x86_xReadCm),
+ /*10067*/ uint16(x86_xArgMoffs16),
+ /*10068*/ uint16(x86_xArgAX),
+ /*10069*/ uint16(x86_xMatch),
+ /*10070*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10072*/ uint16(x86_xReadCm),
+ /*10073*/ uint16(x86_xArgMoffs32),
+ /*10074*/ uint16(x86_xArgEAX),
+ /*10075*/ uint16(x86_xMatch),
+ /*10076*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10078*/ uint16(x86_xReadCm),
+ /*10079*/ uint16(x86_xArgMoffs64),
+ /*10080*/ uint16(x86_xArgRAX),
+ /*10081*/ uint16(x86_xMatch),
+ /*10082*/ uint16(x86_xSetOp), uint16(x86_MOVSB),
+ /*10084*/ uint16(x86_xMatch),
+ /*10085*/ uint16(x86_xCondIs64), 10088, 10098,
+ /*10088*/ uint16(x86_xCondDataSize), 10092, 10095, 0,
+ /*10092*/ uint16(x86_xSetOp), uint16(x86_MOVSW),
+ /*10094*/ uint16(x86_xMatch),
+ /*10095*/ uint16(x86_xSetOp), uint16(x86_MOVSD),
+ /*10097*/ uint16(x86_xMatch),
+ /*10098*/ uint16(x86_xCondDataSize), 10092, 10095, 10102,
+ /*10102*/ uint16(x86_xSetOp), uint16(x86_MOVSQ),
+ /*10104*/ uint16(x86_xMatch),
+ /*10105*/ uint16(x86_xSetOp), uint16(x86_CMPSB),
+ /*10107*/ uint16(x86_xMatch),
+ /*10108*/ uint16(x86_xCondIs64), 10111, 10121,
+ /*10111*/ uint16(x86_xCondDataSize), 10115, 10118, 0,
+ /*10115*/ uint16(x86_xSetOp), uint16(x86_CMPSW),
+ /*10117*/ uint16(x86_xMatch),
+ /*10118*/ uint16(x86_xSetOp), uint16(x86_CMPSD),
+ /*10120*/ uint16(x86_xMatch),
+ /*10121*/ uint16(x86_xCondDataSize), 10115, 10118, 10125,
+ /*10125*/ uint16(x86_xSetOp), uint16(x86_CMPSQ),
+ /*10127*/ uint16(x86_xMatch),
+ /*10128*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*10130*/ uint16(x86_xReadIb),
+ /*10131*/ uint16(x86_xArgAL),
+ /*10132*/ uint16(x86_xArgImm8u),
+ /*10133*/ uint16(x86_xMatch),
+ /*10134*/ uint16(x86_xCondIs64), 10137, 10153,
+ /*10137*/ uint16(x86_xCondDataSize), 10141, 10147, 0,
+ /*10141*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*10143*/ uint16(x86_xReadIw),
+ /*10144*/ uint16(x86_xArgAX),
+ /*10145*/ uint16(x86_xArgImm16),
+ /*10146*/ uint16(x86_xMatch),
+ /*10147*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*10149*/ uint16(x86_xReadId),
+ /*10150*/ uint16(x86_xArgEAX),
+ /*10151*/ uint16(x86_xArgImm32),
+ /*10152*/ uint16(x86_xMatch),
+ /*10153*/ uint16(x86_xCondDataSize), 10141, 10147, 10157,
+ /*10157*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*10159*/ uint16(x86_xReadId),
+ /*10160*/ uint16(x86_xArgRAX),
+ /*10161*/ uint16(x86_xArgImm32),
+ /*10162*/ uint16(x86_xMatch),
+ /*10163*/ uint16(x86_xSetOp), uint16(x86_STOSB),
+ /*10165*/ uint16(x86_xMatch),
+ /*10166*/ uint16(x86_xCondIs64), 10169, 10179,
+ /*10169*/ uint16(x86_xCondDataSize), 10173, 10176, 0,
+ /*10173*/ uint16(x86_xSetOp), uint16(x86_STOSW),
+ /*10175*/ uint16(x86_xMatch),
+ /*10176*/ uint16(x86_xSetOp), uint16(x86_STOSD),
+ /*10178*/ uint16(x86_xMatch),
+ /*10179*/ uint16(x86_xCondDataSize), 10173, 10176, 10183,
+ /*10183*/ uint16(x86_xSetOp), uint16(x86_STOSQ),
+ /*10185*/ uint16(x86_xMatch),
+ /*10186*/ uint16(x86_xSetOp), uint16(x86_LODSB),
+ /*10188*/ uint16(x86_xMatch),
+ /*10189*/ uint16(x86_xCondIs64), 10192, 10202,
+ /*10192*/ uint16(x86_xCondDataSize), 10196, 10199, 0,
+ /*10196*/ uint16(x86_xSetOp), uint16(x86_LODSW),
+ /*10198*/ uint16(x86_xMatch),
+ /*10199*/ uint16(x86_xSetOp), uint16(x86_LODSD),
+ /*10201*/ uint16(x86_xMatch),
+ /*10202*/ uint16(x86_xCondDataSize), 10196, 10199, 10206,
+ /*10206*/ uint16(x86_xSetOp), uint16(x86_LODSQ),
+ /*10208*/ uint16(x86_xMatch),
+ /*10209*/ uint16(x86_xSetOp), uint16(x86_SCASB),
+ /*10211*/ uint16(x86_xMatch),
+ /*10212*/ uint16(x86_xCondIs64), 10215, 10225,
+ /*10215*/ uint16(x86_xCondDataSize), 10219, 10222, 0,
+ /*10219*/ uint16(x86_xSetOp), uint16(x86_SCASW),
+ /*10221*/ uint16(x86_xMatch),
+ /*10222*/ uint16(x86_xSetOp), uint16(x86_SCASD),
+ /*10224*/ uint16(x86_xMatch),
+ /*10225*/ uint16(x86_xCondDataSize), 10219, 10222, 10229,
+ /*10229*/ uint16(x86_xSetOp), uint16(x86_SCASQ),
+ /*10231*/ uint16(x86_xMatch),
+ /*10232*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10234*/ uint16(x86_xReadIb),
+ /*10235*/ uint16(x86_xArgR8op),
+ /*10236*/ uint16(x86_xArgImm8u),
+ /*10237*/ uint16(x86_xMatch),
+ /*10238*/ uint16(x86_xCondIs64), 10241, 10257,
+ /*10241*/ uint16(x86_xCondDataSize), 10245, 10251, 0,
+ /*10245*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10247*/ uint16(x86_xReadIw),
+ /*10248*/ uint16(x86_xArgR16op),
+ /*10249*/ uint16(x86_xArgImm16),
+ /*10250*/ uint16(x86_xMatch),
+ /*10251*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10253*/ uint16(x86_xReadId),
+ /*10254*/ uint16(x86_xArgR32op),
+ /*10255*/ uint16(x86_xArgImm32),
+ /*10256*/ uint16(x86_xMatch),
+ /*10257*/ uint16(x86_xCondDataSize), 10245, 10251, 10261,
+ /*10261*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10263*/ uint16(x86_xReadIo),
+ /*10264*/ uint16(x86_xArgR64op),
+ /*10265*/ uint16(x86_xArgImm64),
+ /*10266*/ uint16(x86_xMatch),
+ /*10267*/ uint16(x86_xCondSlashR),
+ 10276, // 0
+ 10282, // 1
+ 10288, // 2
+ 10294, // 3
+ 10300, // 4
+ 10306, // 5
+ 0, // 6
+ 10312, // 7
+ /*10276*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10278*/ uint16(x86_xReadIb),
+ /*10279*/ uint16(x86_xArgRM8),
+ /*10280*/ uint16(x86_xArgImm8u),
+ /*10281*/ uint16(x86_xMatch),
+ /*10282*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10284*/ uint16(x86_xReadIb),
+ /*10285*/ uint16(x86_xArgRM8),
+ /*10286*/ uint16(x86_xArgImm8u),
+ /*10287*/ uint16(x86_xMatch),
+ /*10288*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10290*/ uint16(x86_xReadIb),
+ /*10291*/ uint16(x86_xArgRM8),
+ /*10292*/ uint16(x86_xArgImm8u),
+ /*10293*/ uint16(x86_xMatch),
+ /*10294*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10296*/ uint16(x86_xReadIb),
+ /*10297*/ uint16(x86_xArgRM8),
+ /*10298*/ uint16(x86_xArgImm8u),
+ /*10299*/ uint16(x86_xMatch),
+ /*10300*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10302*/ uint16(x86_xReadIb),
+ /*10303*/ uint16(x86_xArgRM8),
+ /*10304*/ uint16(x86_xArgImm8u),
+ /*10305*/ uint16(x86_xMatch),
+ /*10306*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10308*/ uint16(x86_xReadIb),
+ /*10309*/ uint16(x86_xArgRM8),
+ /*10310*/ uint16(x86_xArgImm8u),
+ /*10311*/ uint16(x86_xMatch),
+ /*10312*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10314*/ uint16(x86_xReadIb),
+ /*10315*/ uint16(x86_xArgRM8),
+ /*10316*/ uint16(x86_xArgImm8u),
+ /*10317*/ uint16(x86_xMatch),
+ /*10318*/ uint16(x86_xCondSlashR),
+ 10327, // 0
+ 10349, // 1
+ 10371, // 2
+ 10400, // 3
+ 10429, // 4
+ 10458, // 5
+ 0, // 6
+ 10487, // 7
+ /*10327*/ uint16(x86_xCondDataSize), 10331, 10337, 10343,
+ /*10331*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10333*/ uint16(x86_xReadIb),
+ /*10334*/ uint16(x86_xArgRM16),
+ /*10335*/ uint16(x86_xArgImm8u),
+ /*10336*/ uint16(x86_xMatch),
+ /*10337*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10339*/ uint16(x86_xReadIb),
+ /*10340*/ uint16(x86_xArgRM32),
+ /*10341*/ uint16(x86_xArgImm8u),
+ /*10342*/ uint16(x86_xMatch),
+ /*10343*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10345*/ uint16(x86_xReadIb),
+ /*10346*/ uint16(x86_xArgRM64),
+ /*10347*/ uint16(x86_xArgImm8u),
+ /*10348*/ uint16(x86_xMatch),
+ /*10349*/ uint16(x86_xCondDataSize), 10353, 10359, 10365,
+ /*10353*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10355*/ uint16(x86_xReadIb),
+ /*10356*/ uint16(x86_xArgRM16),
+ /*10357*/ uint16(x86_xArgImm8u),
+ /*10358*/ uint16(x86_xMatch),
+ /*10359*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10361*/ uint16(x86_xReadIb),
+ /*10362*/ uint16(x86_xArgRM32),
+ /*10363*/ uint16(x86_xArgImm8u),
+ /*10364*/ uint16(x86_xMatch),
+ /*10365*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10367*/ uint16(x86_xReadIb),
+ /*10368*/ uint16(x86_xArgRM64),
+ /*10369*/ uint16(x86_xArgImm8u),
+ /*10370*/ uint16(x86_xMatch),
+ /*10371*/ uint16(x86_xCondIs64), 10374, 10390,
+ /*10374*/ uint16(x86_xCondDataSize), 10378, 10384, 0,
+ /*10378*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10380*/ uint16(x86_xReadIb),
+ /*10381*/ uint16(x86_xArgRM16),
+ /*10382*/ uint16(x86_xArgImm8u),
+ /*10383*/ uint16(x86_xMatch),
+ /*10384*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10386*/ uint16(x86_xReadIb),
+ /*10387*/ uint16(x86_xArgRM32),
+ /*10388*/ uint16(x86_xArgImm8u),
+ /*10389*/ uint16(x86_xMatch),
+ /*10390*/ uint16(x86_xCondDataSize), 10378, 10384, 10394,
+ /*10394*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10396*/ uint16(x86_xReadIb),
+ /*10397*/ uint16(x86_xArgRM64),
+ /*10398*/ uint16(x86_xArgImm8u),
+ /*10399*/ uint16(x86_xMatch),
+ /*10400*/ uint16(x86_xCondIs64), 10403, 10419,
+ /*10403*/ uint16(x86_xCondDataSize), 10407, 10413, 0,
+ /*10407*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10409*/ uint16(x86_xReadIb),
+ /*10410*/ uint16(x86_xArgRM16),
+ /*10411*/ uint16(x86_xArgImm8u),
+ /*10412*/ uint16(x86_xMatch),
+ /*10413*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10415*/ uint16(x86_xReadIb),
+ /*10416*/ uint16(x86_xArgRM32),
+ /*10417*/ uint16(x86_xArgImm8u),
+ /*10418*/ uint16(x86_xMatch),
+ /*10419*/ uint16(x86_xCondDataSize), 10407, 10413, 10423,
+ /*10423*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10425*/ uint16(x86_xReadIb),
+ /*10426*/ uint16(x86_xArgRM64),
+ /*10427*/ uint16(x86_xArgImm8u),
+ /*10428*/ uint16(x86_xMatch),
+ /*10429*/ uint16(x86_xCondIs64), 10432, 10448,
+ /*10432*/ uint16(x86_xCondDataSize), 10436, 10442, 0,
+ /*10436*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10438*/ uint16(x86_xReadIb),
+ /*10439*/ uint16(x86_xArgRM16),
+ /*10440*/ uint16(x86_xArgImm8u),
+ /*10441*/ uint16(x86_xMatch),
+ /*10442*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10444*/ uint16(x86_xReadIb),
+ /*10445*/ uint16(x86_xArgRM32),
+ /*10446*/ uint16(x86_xArgImm8u),
+ /*10447*/ uint16(x86_xMatch),
+ /*10448*/ uint16(x86_xCondDataSize), 10436, 10442, 10452,
+ /*10452*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10454*/ uint16(x86_xReadIb),
+ /*10455*/ uint16(x86_xArgRM64),
+ /*10456*/ uint16(x86_xArgImm8u),
+ /*10457*/ uint16(x86_xMatch),
+ /*10458*/ uint16(x86_xCondIs64), 10461, 10477,
+ /*10461*/ uint16(x86_xCondDataSize), 10465, 10471, 0,
+ /*10465*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10467*/ uint16(x86_xReadIb),
+ /*10468*/ uint16(x86_xArgRM16),
+ /*10469*/ uint16(x86_xArgImm8u),
+ /*10470*/ uint16(x86_xMatch),
+ /*10471*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10473*/ uint16(x86_xReadIb),
+ /*10474*/ uint16(x86_xArgRM32),
+ /*10475*/ uint16(x86_xArgImm8u),
+ /*10476*/ uint16(x86_xMatch),
+ /*10477*/ uint16(x86_xCondDataSize), 10465, 10471, 10481,
+ /*10481*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10483*/ uint16(x86_xReadIb),
+ /*10484*/ uint16(x86_xArgRM64),
+ /*10485*/ uint16(x86_xArgImm8u),
+ /*10486*/ uint16(x86_xMatch),
+ /*10487*/ uint16(x86_xCondIs64), 10490, 10506,
+ /*10490*/ uint16(x86_xCondDataSize), 10494, 10500, 0,
+ /*10494*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10496*/ uint16(x86_xReadIb),
+ /*10497*/ uint16(x86_xArgRM16),
+ /*10498*/ uint16(x86_xArgImm8u),
+ /*10499*/ uint16(x86_xMatch),
+ /*10500*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10502*/ uint16(x86_xReadIb),
+ /*10503*/ uint16(x86_xArgRM32),
+ /*10504*/ uint16(x86_xArgImm8u),
+ /*10505*/ uint16(x86_xMatch),
+ /*10506*/ uint16(x86_xCondDataSize), 10494, 10500, 10510,
+ /*10510*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10512*/ uint16(x86_xReadIb),
+ /*10513*/ uint16(x86_xArgRM64),
+ /*10514*/ uint16(x86_xArgImm8u),
+ /*10515*/ uint16(x86_xMatch),
+ /*10516*/ uint16(x86_xSetOp), uint16(x86_RET),
+ /*10518*/ uint16(x86_xReadIw),
+ /*10519*/ uint16(x86_xArgImm16u),
+ /*10520*/ uint16(x86_xMatch),
+ /*10521*/ uint16(x86_xSetOp), uint16(x86_RET),
+ /*10523*/ uint16(x86_xMatch),
+ /*10524*/ uint16(x86_xCondIs64), 10527, 0,
+ /*10527*/ uint16(x86_xCondDataSize), 10531, 10537, 0,
+ /*10531*/ uint16(x86_xSetOp), uint16(x86_LES),
+ /*10533*/ uint16(x86_xReadSlashR),
+ /*10534*/ uint16(x86_xArgR16),
+ /*10535*/ uint16(x86_xArgM16colon16),
+ /*10536*/ uint16(x86_xMatch),
+ /*10537*/ uint16(x86_xSetOp), uint16(x86_LES),
+ /*10539*/ uint16(x86_xReadSlashR),
+ /*10540*/ uint16(x86_xArgR32),
+ /*10541*/ uint16(x86_xArgM16colon32),
+ /*10542*/ uint16(x86_xMatch),
+ /*10543*/ uint16(x86_xCondIs64), 10546, 0,
+ /*10546*/ uint16(x86_xCondDataSize), 10550, 10556, 0,
+ /*10550*/ uint16(x86_xSetOp), uint16(x86_LDS),
+ /*10552*/ uint16(x86_xReadSlashR),
+ /*10553*/ uint16(x86_xArgR16),
+ /*10554*/ uint16(x86_xArgM16colon16),
+ /*10555*/ uint16(x86_xMatch),
+ /*10556*/ uint16(x86_xSetOp), uint16(x86_LDS),
+ /*10558*/ uint16(x86_xReadSlashR),
+ /*10559*/ uint16(x86_xArgR32),
+ /*10560*/ uint16(x86_xArgM16colon32),
+ /*10561*/ uint16(x86_xMatch),
+ /*10562*/ uint16(x86_xCondByte), 1,
+ 0xF8, 10581,
+ /*10566*/ uint16(x86_xCondSlashR),
+ 10575, // 0
+ 0, // 1
+ 0, // 2
+ 0, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*10575*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10577*/ uint16(x86_xReadIb),
+ /*10578*/ uint16(x86_xArgRM8),
+ /*10579*/ uint16(x86_xArgImm8u),
+ /*10580*/ uint16(x86_xMatch),
+ /*10581*/ uint16(x86_xSetOp), uint16(x86_XABORT),
+ /*10583*/ uint16(x86_xReadIb),
+ /*10584*/ uint16(x86_xArgImm8u),
+ /*10585*/ uint16(x86_xMatch),
+ /*10586*/ uint16(x86_xCondByte), 1,
+ 0xF8, 10628,
+ /*10590*/ uint16(x86_xCondSlashR),
+ 10599, // 0
+ 0, // 1
+ 0, // 2
+ 0, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*10599*/ uint16(x86_xCondIs64), 10602, 10618,
+ /*10602*/ uint16(x86_xCondDataSize), 10606, 10612, 0,
+ /*10606*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10608*/ uint16(x86_xReadIw),
+ /*10609*/ uint16(x86_xArgRM16),
+ /*10610*/ uint16(x86_xArgImm16),
+ /*10611*/ uint16(x86_xMatch),
+ /*10612*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10614*/ uint16(x86_xReadId),
+ /*10615*/ uint16(x86_xArgRM32),
+ /*10616*/ uint16(x86_xArgImm32),
+ /*10617*/ uint16(x86_xMatch),
+ /*10618*/ uint16(x86_xCondDataSize), 10606, 10612, 10622,
+ /*10622*/ uint16(x86_xSetOp), uint16(x86_MOV),
+ /*10624*/ uint16(x86_xReadId),
+ /*10625*/ uint16(x86_xArgRM64),
+ /*10626*/ uint16(x86_xArgImm32),
+ /*10627*/ uint16(x86_xMatch),
+ /*10628*/ uint16(x86_xCondDataSize), 10632, 10637, 10642,
+ /*10632*/ uint16(x86_xSetOp), uint16(x86_XBEGIN),
+ /*10634*/ uint16(x86_xReadCw),
+ /*10635*/ uint16(x86_xArgRel16),
+ /*10636*/ uint16(x86_xMatch),
+ /*10637*/ uint16(x86_xSetOp), uint16(x86_XBEGIN),
+ /*10639*/ uint16(x86_xReadCd),
+ /*10640*/ uint16(x86_xArgRel32),
+ /*10641*/ uint16(x86_xMatch),
+ /*10642*/ uint16(x86_xSetOp), uint16(x86_XBEGIN),
+ /*10644*/ uint16(x86_xReadCd),
+ /*10645*/ uint16(x86_xArgRel32),
+ /*10646*/ uint16(x86_xMatch),
+ /*10647*/ uint16(x86_xSetOp), uint16(x86_ENTER),
+ /*10649*/ uint16(x86_xReadIw),
+ /*10650*/ uint16(x86_xReadIb),
+ /*10651*/ uint16(x86_xArgImm16u),
+ /*10652*/ uint16(x86_xArgImm8u),
+ /*10653*/ uint16(x86_xMatch),
+ /*10654*/ uint16(x86_xCondIs64), 10657, 10667,
+ /*10657*/ uint16(x86_xCondDataSize), 10661, 10664, 0,
+ /*10661*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
+ /*10663*/ uint16(x86_xMatch),
+ /*10664*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
+ /*10666*/ uint16(x86_xMatch),
+ /*10667*/ uint16(x86_xCondDataSize), 10661, 10671, 10674,
+ /*10671*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
+ /*10673*/ uint16(x86_xMatch),
+ /*10674*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
+ /*10676*/ uint16(x86_xMatch),
+ /*10677*/ uint16(x86_xSetOp), uint16(x86_LRET),
+ /*10679*/ uint16(x86_xReadIw),
+ /*10680*/ uint16(x86_xArgImm16u),
+ /*10681*/ uint16(x86_xMatch),
+ /*10682*/ uint16(x86_xSetOp), uint16(x86_LRET),
+ /*10684*/ uint16(x86_xMatch),
+ /*10685*/ uint16(x86_xSetOp), uint16(x86_INT),
+ /*10687*/ uint16(x86_xArg3),
+ /*10688*/ uint16(x86_xMatch),
+ /*10689*/ uint16(x86_xSetOp), uint16(x86_INT),
+ /*10691*/ uint16(x86_xReadIb),
+ /*10692*/ uint16(x86_xArgImm8u),
+ /*10693*/ uint16(x86_xMatch),
+ /*10694*/ uint16(x86_xCondIs64), 10697, 0,
+ /*10697*/ uint16(x86_xSetOp), uint16(x86_INTO),
+ /*10699*/ uint16(x86_xMatch),
+ /*10700*/ uint16(x86_xCondIs64), 10703, 10713,
+ /*10703*/ uint16(x86_xCondDataSize), 10707, 10710, 0,
+ /*10707*/ uint16(x86_xSetOp), uint16(x86_IRET),
+ /*10709*/ uint16(x86_xMatch),
+ /*10710*/ uint16(x86_xSetOp), uint16(x86_IRETD),
+ /*10712*/ uint16(x86_xMatch),
+ /*10713*/ uint16(x86_xCondDataSize), 10707, 10710, 10717,
+ /*10717*/ uint16(x86_xSetOp), uint16(x86_IRETQ),
+ /*10719*/ uint16(x86_xMatch),
+ /*10720*/ uint16(x86_xCondSlashR),
+ 10729, // 0
+ 10734, // 1
+ 10739, // 2
+ 10744, // 3
+ 10749, // 4
+ 10754, // 5
+ 0, // 6
+ 10759, // 7
+ /*10729*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10731*/ uint16(x86_xArgRM8),
+ /*10732*/ uint16(x86_xArg1),
+ /*10733*/ uint16(x86_xMatch),
+ /*10734*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10736*/ uint16(x86_xArgRM8),
+ /*10737*/ uint16(x86_xArg1),
+ /*10738*/ uint16(x86_xMatch),
+ /*10739*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10741*/ uint16(x86_xArgRM8),
+ /*10742*/ uint16(x86_xArg1),
+ /*10743*/ uint16(x86_xMatch),
+ /*10744*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10746*/ uint16(x86_xArgRM8),
+ /*10747*/ uint16(x86_xArg1),
+ /*10748*/ uint16(x86_xMatch),
+ /*10749*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10751*/ uint16(x86_xArgRM8),
+ /*10752*/ uint16(x86_xArg1),
+ /*10753*/ uint16(x86_xMatch),
+ /*10754*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10756*/ uint16(x86_xArgRM8),
+ /*10757*/ uint16(x86_xArg1),
+ /*10758*/ uint16(x86_xMatch),
+ /*10759*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10761*/ uint16(x86_xArgRM8),
+ /*10762*/ uint16(x86_xArg1),
+ /*10763*/ uint16(x86_xMatch),
+ /*10764*/ uint16(x86_xCondSlashR),
+ 10773, // 0
+ 10799, // 1
+ 10825, // 2
+ 10851, // 3
+ 10877, // 4
+ 10903, // 5
+ 0, // 6
+ 10929, // 7
+ /*10773*/ uint16(x86_xCondIs64), 10776, 10790,
+ /*10776*/ uint16(x86_xCondDataSize), 10780, 10785, 0,
+ /*10780*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10782*/ uint16(x86_xArgRM16),
+ /*10783*/ uint16(x86_xArg1),
+ /*10784*/ uint16(x86_xMatch),
+ /*10785*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10787*/ uint16(x86_xArgRM32),
+ /*10788*/ uint16(x86_xArg1),
+ /*10789*/ uint16(x86_xMatch),
+ /*10790*/ uint16(x86_xCondDataSize), 10780, 10785, 10794,
+ /*10794*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10796*/ uint16(x86_xArgRM64),
+ /*10797*/ uint16(x86_xArg1),
+ /*10798*/ uint16(x86_xMatch),
+ /*10799*/ uint16(x86_xCondIs64), 10802, 10816,
+ /*10802*/ uint16(x86_xCondDataSize), 10806, 10811, 0,
+ /*10806*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10808*/ uint16(x86_xArgRM16),
+ /*10809*/ uint16(x86_xArg1),
+ /*10810*/ uint16(x86_xMatch),
+ /*10811*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10813*/ uint16(x86_xArgRM32),
+ /*10814*/ uint16(x86_xArg1),
+ /*10815*/ uint16(x86_xMatch),
+ /*10816*/ uint16(x86_xCondDataSize), 10806, 10811, 10820,
+ /*10820*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10822*/ uint16(x86_xArgRM64),
+ /*10823*/ uint16(x86_xArg1),
+ /*10824*/ uint16(x86_xMatch),
+ /*10825*/ uint16(x86_xCondIs64), 10828, 10842,
+ /*10828*/ uint16(x86_xCondDataSize), 10832, 10837, 0,
+ /*10832*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10834*/ uint16(x86_xArgRM16),
+ /*10835*/ uint16(x86_xArg1),
+ /*10836*/ uint16(x86_xMatch),
+ /*10837*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10839*/ uint16(x86_xArgRM32),
+ /*10840*/ uint16(x86_xArg1),
+ /*10841*/ uint16(x86_xMatch),
+ /*10842*/ uint16(x86_xCondDataSize), 10832, 10837, 10846,
+ /*10846*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10848*/ uint16(x86_xArgRM64),
+ /*10849*/ uint16(x86_xArg1),
+ /*10850*/ uint16(x86_xMatch),
+ /*10851*/ uint16(x86_xCondIs64), 10854, 10868,
+ /*10854*/ uint16(x86_xCondDataSize), 10858, 10863, 0,
+ /*10858*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10860*/ uint16(x86_xArgRM16),
+ /*10861*/ uint16(x86_xArg1),
+ /*10862*/ uint16(x86_xMatch),
+ /*10863*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10865*/ uint16(x86_xArgRM32),
+ /*10866*/ uint16(x86_xArg1),
+ /*10867*/ uint16(x86_xMatch),
+ /*10868*/ uint16(x86_xCondDataSize), 10858, 10863, 10872,
+ /*10872*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10874*/ uint16(x86_xArgRM64),
+ /*10875*/ uint16(x86_xArg1),
+ /*10876*/ uint16(x86_xMatch),
+ /*10877*/ uint16(x86_xCondIs64), 10880, 10894,
+ /*10880*/ uint16(x86_xCondDataSize), 10884, 10889, 0,
+ /*10884*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10886*/ uint16(x86_xArgRM16),
+ /*10887*/ uint16(x86_xArg1),
+ /*10888*/ uint16(x86_xMatch),
+ /*10889*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10891*/ uint16(x86_xArgRM32),
+ /*10892*/ uint16(x86_xArg1),
+ /*10893*/ uint16(x86_xMatch),
+ /*10894*/ uint16(x86_xCondDataSize), 10884, 10889, 10898,
+ /*10898*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10900*/ uint16(x86_xArgRM64),
+ /*10901*/ uint16(x86_xArg1),
+ /*10902*/ uint16(x86_xMatch),
+ /*10903*/ uint16(x86_xCondIs64), 10906, 10920,
+ /*10906*/ uint16(x86_xCondDataSize), 10910, 10915, 0,
+ /*10910*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10912*/ uint16(x86_xArgRM16),
+ /*10913*/ uint16(x86_xArg1),
+ /*10914*/ uint16(x86_xMatch),
+ /*10915*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10917*/ uint16(x86_xArgRM32),
+ /*10918*/ uint16(x86_xArg1),
+ /*10919*/ uint16(x86_xMatch),
+ /*10920*/ uint16(x86_xCondDataSize), 10910, 10915, 10924,
+ /*10924*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10926*/ uint16(x86_xArgRM64),
+ /*10927*/ uint16(x86_xArg1),
+ /*10928*/ uint16(x86_xMatch),
+ /*10929*/ uint16(x86_xCondIs64), 10932, 10946,
+ /*10932*/ uint16(x86_xCondDataSize), 10936, 10941, 0,
+ /*10936*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10938*/ uint16(x86_xArgRM16),
+ /*10939*/ uint16(x86_xArg1),
+ /*10940*/ uint16(x86_xMatch),
+ /*10941*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10943*/ uint16(x86_xArgRM32),
+ /*10944*/ uint16(x86_xArg1),
+ /*10945*/ uint16(x86_xMatch),
+ /*10946*/ uint16(x86_xCondDataSize), 10936, 10941, 10950,
+ /*10950*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10952*/ uint16(x86_xArgRM64),
+ /*10953*/ uint16(x86_xArg1),
+ /*10954*/ uint16(x86_xMatch),
+ /*10955*/ uint16(x86_xCondSlashR),
+ 10964, // 0
+ 10969, // 1
+ 10974, // 2
+ 10979, // 3
+ 10984, // 4
+ 10989, // 5
+ 0, // 6
+ 10994, // 7
+ /*10964*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*10966*/ uint16(x86_xArgRM8),
+ /*10967*/ uint16(x86_xArgCL),
+ /*10968*/ uint16(x86_xMatch),
+ /*10969*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*10971*/ uint16(x86_xArgRM8),
+ /*10972*/ uint16(x86_xArgCL),
+ /*10973*/ uint16(x86_xMatch),
+ /*10974*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*10976*/ uint16(x86_xArgRM8),
+ /*10977*/ uint16(x86_xArgCL),
+ /*10978*/ uint16(x86_xMatch),
+ /*10979*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*10981*/ uint16(x86_xArgRM8),
+ /*10982*/ uint16(x86_xArgCL),
+ /*10983*/ uint16(x86_xMatch),
+ /*10984*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*10986*/ uint16(x86_xArgRM8),
+ /*10987*/ uint16(x86_xArgCL),
+ /*10988*/ uint16(x86_xMatch),
+ /*10989*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*10991*/ uint16(x86_xArgRM8),
+ /*10992*/ uint16(x86_xArgCL),
+ /*10993*/ uint16(x86_xMatch),
+ /*10994*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*10996*/ uint16(x86_xArgRM8),
+ /*10997*/ uint16(x86_xArgCL),
+ /*10998*/ uint16(x86_xMatch),
+ /*10999*/ uint16(x86_xCondSlashR),
+ 11008, // 0
+ 11034, // 1
+ 11060, // 2
+ 11086, // 3
+ 11112, // 4
+ 11138, // 5
+ 0, // 6
+ 11164, // 7
+ /*11008*/ uint16(x86_xCondIs64), 11011, 11025,
+ /*11011*/ uint16(x86_xCondDataSize), 11015, 11020, 0,
+ /*11015*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*11017*/ uint16(x86_xArgRM16),
+ /*11018*/ uint16(x86_xArgCL),
+ /*11019*/ uint16(x86_xMatch),
+ /*11020*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*11022*/ uint16(x86_xArgRM32),
+ /*11023*/ uint16(x86_xArgCL),
+ /*11024*/ uint16(x86_xMatch),
+ /*11025*/ uint16(x86_xCondDataSize), 11015, 11020, 11029,
+ /*11029*/ uint16(x86_xSetOp), uint16(x86_ROL),
+ /*11031*/ uint16(x86_xArgRM64),
+ /*11032*/ uint16(x86_xArgCL),
+ /*11033*/ uint16(x86_xMatch),
+ /*11034*/ uint16(x86_xCondIs64), 11037, 11051,
+ /*11037*/ uint16(x86_xCondDataSize), 11041, 11046, 0,
+ /*11041*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*11043*/ uint16(x86_xArgRM16),
+ /*11044*/ uint16(x86_xArgCL),
+ /*11045*/ uint16(x86_xMatch),
+ /*11046*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*11048*/ uint16(x86_xArgRM32),
+ /*11049*/ uint16(x86_xArgCL),
+ /*11050*/ uint16(x86_xMatch),
+ /*11051*/ uint16(x86_xCondDataSize), 11041, 11046, 11055,
+ /*11055*/ uint16(x86_xSetOp), uint16(x86_ROR),
+ /*11057*/ uint16(x86_xArgRM64),
+ /*11058*/ uint16(x86_xArgCL),
+ /*11059*/ uint16(x86_xMatch),
+ /*11060*/ uint16(x86_xCondIs64), 11063, 11077,
+ /*11063*/ uint16(x86_xCondDataSize), 11067, 11072, 0,
+ /*11067*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*11069*/ uint16(x86_xArgRM16),
+ /*11070*/ uint16(x86_xArgCL),
+ /*11071*/ uint16(x86_xMatch),
+ /*11072*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*11074*/ uint16(x86_xArgRM32),
+ /*11075*/ uint16(x86_xArgCL),
+ /*11076*/ uint16(x86_xMatch),
+ /*11077*/ uint16(x86_xCondDataSize), 11067, 11072, 11081,
+ /*11081*/ uint16(x86_xSetOp), uint16(x86_RCL),
+ /*11083*/ uint16(x86_xArgRM64),
+ /*11084*/ uint16(x86_xArgCL),
+ /*11085*/ uint16(x86_xMatch),
+ /*11086*/ uint16(x86_xCondIs64), 11089, 11103,
+ /*11089*/ uint16(x86_xCondDataSize), 11093, 11098, 0,
+ /*11093*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*11095*/ uint16(x86_xArgRM16),
+ /*11096*/ uint16(x86_xArgCL),
+ /*11097*/ uint16(x86_xMatch),
+ /*11098*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*11100*/ uint16(x86_xArgRM32),
+ /*11101*/ uint16(x86_xArgCL),
+ /*11102*/ uint16(x86_xMatch),
+ /*11103*/ uint16(x86_xCondDataSize), 11093, 11098, 11107,
+ /*11107*/ uint16(x86_xSetOp), uint16(x86_RCR),
+ /*11109*/ uint16(x86_xArgRM64),
+ /*11110*/ uint16(x86_xArgCL),
+ /*11111*/ uint16(x86_xMatch),
+ /*11112*/ uint16(x86_xCondIs64), 11115, 11129,
+ /*11115*/ uint16(x86_xCondDataSize), 11119, 11124, 0,
+ /*11119*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*11121*/ uint16(x86_xArgRM16),
+ /*11122*/ uint16(x86_xArgCL),
+ /*11123*/ uint16(x86_xMatch),
+ /*11124*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*11126*/ uint16(x86_xArgRM32),
+ /*11127*/ uint16(x86_xArgCL),
+ /*11128*/ uint16(x86_xMatch),
+ /*11129*/ uint16(x86_xCondDataSize), 11119, 11124, 11133,
+ /*11133*/ uint16(x86_xSetOp), uint16(x86_SHL),
+ /*11135*/ uint16(x86_xArgRM64),
+ /*11136*/ uint16(x86_xArgCL),
+ /*11137*/ uint16(x86_xMatch),
+ /*11138*/ uint16(x86_xCondIs64), 11141, 11155,
+ /*11141*/ uint16(x86_xCondDataSize), 11145, 11150, 0,
+ /*11145*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*11147*/ uint16(x86_xArgRM16),
+ /*11148*/ uint16(x86_xArgCL),
+ /*11149*/ uint16(x86_xMatch),
+ /*11150*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*11152*/ uint16(x86_xArgRM32),
+ /*11153*/ uint16(x86_xArgCL),
+ /*11154*/ uint16(x86_xMatch),
+ /*11155*/ uint16(x86_xCondDataSize), 11145, 11150, 11159,
+ /*11159*/ uint16(x86_xSetOp), uint16(x86_SHR),
+ /*11161*/ uint16(x86_xArgRM64),
+ /*11162*/ uint16(x86_xArgCL),
+ /*11163*/ uint16(x86_xMatch),
+ /*11164*/ uint16(x86_xCondIs64), 11167, 11181,
+ /*11167*/ uint16(x86_xCondDataSize), 11171, 11176, 0,
+ /*11171*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*11173*/ uint16(x86_xArgRM16),
+ /*11174*/ uint16(x86_xArgCL),
+ /*11175*/ uint16(x86_xMatch),
+ /*11176*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*11178*/ uint16(x86_xArgRM32),
+ /*11179*/ uint16(x86_xArgCL),
+ /*11180*/ uint16(x86_xMatch),
+ /*11181*/ uint16(x86_xCondDataSize), 11171, 11176, 11185,
+ /*11185*/ uint16(x86_xSetOp), uint16(x86_SAR),
+ /*11187*/ uint16(x86_xArgRM64),
+ /*11188*/ uint16(x86_xArgCL),
+ /*11189*/ uint16(x86_xMatch),
+ /*11190*/ uint16(x86_xCondIs64), 11193, 0,
+ /*11193*/ uint16(x86_xSetOp), uint16(x86_AAM),
+ /*11195*/ uint16(x86_xReadIb),
+ /*11196*/ uint16(x86_xArgImm8u),
+ /*11197*/ uint16(x86_xMatch),
+ /*11198*/ uint16(x86_xCondIs64), 11201, 0,
+ /*11201*/ uint16(x86_xSetOp), uint16(x86_AAD),
+ /*11203*/ uint16(x86_xReadIb),
+ /*11204*/ uint16(x86_xArgImm8u),
+ /*11205*/ uint16(x86_xMatch),
+ /*11206*/ uint16(x86_xCondIs64), 11209, 11212,
+ /*11209*/ uint16(x86_xSetOp), uint16(x86_XLATB),
+ /*11211*/ uint16(x86_xMatch),
+ /*11212*/ uint16(x86_xCondDataSize), 11209, 11209, 11216,
+ /*11216*/ uint16(x86_xSetOp), uint16(x86_XLATB),
+ /*11218*/ uint16(x86_xMatch),
+ /*11219*/ uint16(x86_xCondByte), 64,
+ 0xc0, 11390,
+ 0xc1, 11390,
+ 0xc2, 11390,
+ 0xc3, 11390,
+ 0xc4, 11390,
+ 0xc5, 11390,
+ 0xc6, 11390,
+ 0xc7, 11390,
+ 0xc8, 11395,
+ 0xc9, 11395,
+ 0xca, 11395,
+ 0xcb, 11395,
+ 0xcc, 11395,
+ 0xcd, 11395,
+ 0xce, 11395,
+ 0xcf, 11395,
+ 0xd0, 11400,
+ 0xd1, 11400,
+ 0xd2, 11400,
+ 0xd3, 11400,
+ 0xd4, 11400,
+ 0xd5, 11400,
+ 0xd6, 11400,
+ 0xd7, 11400,
+ 0xd8, 11404,
+ 0xd9, 11404,
+ 0xda, 11404,
+ 0xdb, 11404,
+ 0xdc, 11404,
+ 0xdd, 11404,
+ 0xde, 11404,
+ 0xdf, 11404,
+ 0xe0, 11408,
+ 0xe1, 11408,
+ 0xe2, 11408,
+ 0xe3, 11408,
+ 0xe4, 11408,
+ 0xe5, 11408,
+ 0xe6, 11408,
+ 0xe7, 11408,
+ 0xe8, 11413,
+ 0xe9, 11413,
+ 0xea, 11413,
+ 0xeb, 11413,
+ 0xec, 11413,
+ 0xed, 11413,
+ 0xee, 11413,
+ 0xef, 11413,
+ 0xf0, 11418,
+ 0xf1, 11418,
+ 0xf2, 11418,
+ 0xf3, 11418,
+ 0xf4, 11418,
+ 0xf5, 11418,
+ 0xf6, 11418,
+ 0xf7, 11418,
+ 0xf8, 11423,
+ 0xf9, 11423,
+ 0xfa, 11423,
+ 0xfb, 11423,
+ 0xfc, 11423,
+ 0xfd, 11423,
+ 0xfe, 11423,
+ 0xff, 11423,
+ /*11349*/ uint16(x86_xCondSlashR),
+ 11358, // 0
+ 11362, // 1
+ 11366, // 2
+ 11370, // 3
+ 11374, // 4
+ 11378, // 5
+ 11382, // 6
+ 11386, // 7
+ /*11358*/ uint16(x86_xSetOp), uint16(x86_FADD),
+ /*11360*/ uint16(x86_xArgM32fp),
+ /*11361*/ uint16(x86_xMatch),
+ /*11362*/ uint16(x86_xSetOp), uint16(x86_FMUL),
+ /*11364*/ uint16(x86_xArgM32fp),
+ /*11365*/ uint16(x86_xMatch),
+ /*11366*/ uint16(x86_xSetOp), uint16(x86_FCOM),
+ /*11368*/ uint16(x86_xArgM32fp),
+ /*11369*/ uint16(x86_xMatch),
+ /*11370*/ uint16(x86_xSetOp), uint16(x86_FCOMP),
+ /*11372*/ uint16(x86_xArgM32fp),
+ /*11373*/ uint16(x86_xMatch),
+ /*11374*/ uint16(x86_xSetOp), uint16(x86_FSUB),
+ /*11376*/ uint16(x86_xArgM32fp),
+ /*11377*/ uint16(x86_xMatch),
+ /*11378*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
+ /*11380*/ uint16(x86_xArgM32fp),
+ /*11381*/ uint16(x86_xMatch),
+ /*11382*/ uint16(x86_xSetOp), uint16(x86_FDIV),
+ /*11384*/ uint16(x86_xArgM32fp),
+ /*11385*/ uint16(x86_xMatch),
+ /*11386*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
+ /*11388*/ uint16(x86_xArgM32fp),
+ /*11389*/ uint16(x86_xMatch),
+ /*11390*/ uint16(x86_xSetOp), uint16(x86_FADD),
+ /*11392*/ uint16(x86_xArgST),
+ /*11393*/ uint16(x86_xArgSTi),
+ /*11394*/ uint16(x86_xMatch),
+ /*11395*/ uint16(x86_xSetOp), uint16(x86_FMUL),
+ /*11397*/ uint16(x86_xArgST),
+ /*11398*/ uint16(x86_xArgSTi),
+ /*11399*/ uint16(x86_xMatch),
+ /*11400*/ uint16(x86_xSetOp), uint16(x86_FCOM),
+ /*11402*/ uint16(x86_xArgSTi),
+ /*11403*/ uint16(x86_xMatch),
+ /*11404*/ uint16(x86_xSetOp), uint16(x86_FCOMP),
+ /*11406*/ uint16(x86_xArgSTi),
+ /*11407*/ uint16(x86_xMatch),
+ /*11408*/ uint16(x86_xSetOp), uint16(x86_FSUB),
+ /*11410*/ uint16(x86_xArgST),
+ /*11411*/ uint16(x86_xArgSTi),
+ /*11412*/ uint16(x86_xMatch),
+ /*11413*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
+ /*11415*/ uint16(x86_xArgST),
+ /*11416*/ uint16(x86_xArgSTi),
+ /*11417*/ uint16(x86_xMatch),
+ /*11418*/ uint16(x86_xSetOp), uint16(x86_FDIV),
+ /*11420*/ uint16(x86_xArgST),
+ /*11421*/ uint16(x86_xArgSTi),
+ /*11422*/ uint16(x86_xMatch),
+ /*11423*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
+ /*11425*/ uint16(x86_xArgST),
+ /*11426*/ uint16(x86_xArgSTi),
+ /*11427*/ uint16(x86_xMatch),
+ /*11428*/ uint16(x86_xCondByte), 42,
+ 0xc0, 11551,
+ 0xc1, 11551,
+ 0xc2, 11551,
+ 0xc3, 11551,
+ 0xc4, 11551,
+ 0xc5, 11551,
+ 0xc6, 11551,
+ 0xc7, 11551,
+ 0xc8, 11555,
+ 0xc9, 11555,
+ 0xca, 11555,
+ 0xcb, 11555,
+ 0xcc, 11555,
+ 0xcd, 11555,
+ 0xce, 11555,
+ 0xcf, 11555,
+ 0xD0, 11559,
+ 0xE0, 11562,
+ 0xE1, 11565,
+ 0xE4, 11568,
+ 0xE5, 11571,
+ 0xE8, 11574,
+ 0xE9, 11577,
+ 0xEA, 11580,
+ 0xEB, 11583,
+ 0xEC, 11586,
+ 0xF0, 11589,
+ 0xF1, 11592,
+ 0xF2, 11595,
+ 0xF3, 11598,
+ 0xF4, 11601,
+ 0xF5, 11604,
+ 0xF6, 11607,
+ 0xF7, 11610,
+ 0xF8, 11613,
+ 0xF9, 11616,
+ 0xFA, 11619,
+ 0xFB, 11622,
+ 0xFC, 11625,
+ 0xFD, 11628,
+ 0xFE, 11631,
+ 0xFF, 11634,
+ /*11514*/ uint16(x86_xCondSlashR),
+ 11523, // 0
+ 0, // 1
+ 11527, // 2
+ 11531, // 3
+ 11535, // 4
+ 11539, // 5
+ 11543, // 6
+ 11547, // 7
+ /*11523*/ uint16(x86_xSetOp), uint16(x86_FLD),
+ /*11525*/ uint16(x86_xArgM32fp),
+ /*11526*/ uint16(x86_xMatch),
+ /*11527*/ uint16(x86_xSetOp), uint16(x86_FST),
+ /*11529*/ uint16(x86_xArgM32fp),
+ /*11530*/ uint16(x86_xMatch),
+ /*11531*/ uint16(x86_xSetOp), uint16(x86_FSTP),
+ /*11533*/ uint16(x86_xArgM32fp),
+ /*11534*/ uint16(x86_xMatch),
+ /*11535*/ uint16(x86_xSetOp), uint16(x86_FLDENV),
+ /*11537*/ uint16(x86_xArgM1428byte),
+ /*11538*/ uint16(x86_xMatch),
+ /*11539*/ uint16(x86_xSetOp), uint16(x86_FLDCW),
+ /*11541*/ uint16(x86_xArgM2byte),
+ /*11542*/ uint16(x86_xMatch),
+ /*11543*/ uint16(x86_xSetOp), uint16(x86_FNSTENV),
+ /*11545*/ uint16(x86_xArgM1428byte),
+ /*11546*/ uint16(x86_xMatch),
+ /*11547*/ uint16(x86_xSetOp), uint16(x86_FNSTCW),
+ /*11549*/ uint16(x86_xArgM2byte),
+ /*11550*/ uint16(x86_xMatch),
+ /*11551*/ uint16(x86_xSetOp), uint16(x86_FLD),
+ /*11553*/ uint16(x86_xArgSTi),
+ /*11554*/ uint16(x86_xMatch),
+ /*11555*/ uint16(x86_xSetOp), uint16(x86_FXCH),
+ /*11557*/ uint16(x86_xArgSTi),
+ /*11558*/ uint16(x86_xMatch),
+ /*11559*/ uint16(x86_xSetOp), uint16(x86_FNOP),
+ /*11561*/ uint16(x86_xMatch),
+ /*11562*/ uint16(x86_xSetOp), uint16(x86_FCHS),
+ /*11564*/ uint16(x86_xMatch),
+ /*11565*/ uint16(x86_xSetOp), uint16(x86_FABS),
+ /*11567*/ uint16(x86_xMatch),
+ /*11568*/ uint16(x86_xSetOp), uint16(x86_FTST),
+ /*11570*/ uint16(x86_xMatch),
+ /*11571*/ uint16(x86_xSetOp), uint16(x86_FXAM),
+ /*11573*/ uint16(x86_xMatch),
+ /*11574*/ uint16(x86_xSetOp), uint16(x86_FLD1),
+ /*11576*/ uint16(x86_xMatch),
+ /*11577*/ uint16(x86_xSetOp), uint16(x86_FLDL2T),
+ /*11579*/ uint16(x86_xMatch),
+ /*11580*/ uint16(x86_xSetOp), uint16(x86_FLDL2E),
+ /*11582*/ uint16(x86_xMatch),
+ /*11583*/ uint16(x86_xSetOp), uint16(x86_FLDPI),
+ /*11585*/ uint16(x86_xMatch),
+ /*11586*/ uint16(x86_xSetOp), uint16(x86_FLDLG2),
+ /*11588*/ uint16(x86_xMatch),
+ /*11589*/ uint16(x86_xSetOp), uint16(x86_F2XM1),
+ /*11591*/ uint16(x86_xMatch),
+ /*11592*/ uint16(x86_xSetOp), uint16(x86_FYL2X),
+ /*11594*/ uint16(x86_xMatch),
+ /*11595*/ uint16(x86_xSetOp), uint16(x86_FPTAN),
+ /*11597*/ uint16(x86_xMatch),
+ /*11598*/ uint16(x86_xSetOp), uint16(x86_FPATAN),
+ /*11600*/ uint16(x86_xMatch),
+ /*11601*/ uint16(x86_xSetOp), uint16(x86_FXTRACT),
+ /*11603*/ uint16(x86_xMatch),
+ /*11604*/ uint16(x86_xSetOp), uint16(x86_FPREM1),
+ /*11606*/ uint16(x86_xMatch),
+ /*11607*/ uint16(x86_xSetOp), uint16(x86_FDECSTP),
+ /*11609*/ uint16(x86_xMatch),
+ /*11610*/ uint16(x86_xSetOp), uint16(x86_FINCSTP),
+ /*11612*/ uint16(x86_xMatch),
+ /*11613*/ uint16(x86_xSetOp), uint16(x86_FPREM),
+ /*11615*/ uint16(x86_xMatch),
+ /*11616*/ uint16(x86_xSetOp), uint16(x86_FYL2XP1),
+ /*11618*/ uint16(x86_xMatch),
+ /*11619*/ uint16(x86_xSetOp), uint16(x86_FSQRT),
+ /*11621*/ uint16(x86_xMatch),
+ /*11622*/ uint16(x86_xSetOp), uint16(x86_FSINCOS),
+ /*11624*/ uint16(x86_xMatch),
+ /*11625*/ uint16(x86_xSetOp), uint16(x86_FRNDINT),
+ /*11627*/ uint16(x86_xMatch),
+ /*11628*/ uint16(x86_xSetOp), uint16(x86_FSCALE),
+ /*11630*/ uint16(x86_xMatch),
+ /*11631*/ uint16(x86_xSetOp), uint16(x86_FSIN),
+ /*11633*/ uint16(x86_xMatch),
+ /*11634*/ uint16(x86_xSetOp), uint16(x86_FCOS),
+ /*11636*/ uint16(x86_xMatch),
+ /*11637*/ uint16(x86_xCondByte), 33,
+ 0xc0, 11746,
+ 0xc1, 11746,
+ 0xc2, 11746,
+ 0xc3, 11746,
+ 0xc4, 11746,
+ 0xc5, 11746,
+ 0xc6, 11746,
+ 0xc7, 11746,
+ 0xc8, 11751,
+ 0xc9, 11751,
+ 0xca, 11751,
+ 0xcb, 11751,
+ 0xcc, 11751,
+ 0xcd, 11751,
+ 0xce, 11751,
+ 0xcf, 11751,
+ 0xd0, 11756,
+ 0xd1, 11756,
+ 0xd2, 11756,
+ 0xd3, 11756,
+ 0xd4, 11756,
+ 0xd5, 11756,
+ 0xd6, 11756,
+ 0xd7, 11756,
+ 0xd8, 11761,
+ 0xd9, 11761,
+ 0xda, 11761,
+ 0xdb, 11761,
+ 0xdc, 11761,
+ 0xdd, 11761,
+ 0xde, 11761,
+ 0xdf, 11761,
+ 0xE9, 11766,
+ /*11705*/ uint16(x86_xCondSlashR),
+ 11714, // 0
+ 11718, // 1
+ 11722, // 2
+ 11726, // 3
+ 11730, // 4
+ 11734, // 5
+ 11738, // 6
+ 11742, // 7
+ /*11714*/ uint16(x86_xSetOp), uint16(x86_FIADD),
+ /*11716*/ uint16(x86_xArgM32int),
+ /*11717*/ uint16(x86_xMatch),
+ /*11718*/ uint16(x86_xSetOp), uint16(x86_FIMUL),
+ /*11720*/ uint16(x86_xArgM32int),
+ /*11721*/ uint16(x86_xMatch),
+ /*11722*/ uint16(x86_xSetOp), uint16(x86_FICOM),
+ /*11724*/ uint16(x86_xArgM32int),
+ /*11725*/ uint16(x86_xMatch),
+ /*11726*/ uint16(x86_xSetOp), uint16(x86_FICOMP),
+ /*11728*/ uint16(x86_xArgM32int),
+ /*11729*/ uint16(x86_xMatch),
+ /*11730*/ uint16(x86_xSetOp), uint16(x86_FISUB),
+ /*11732*/ uint16(x86_xArgM32int),
+ /*11733*/ uint16(x86_xMatch),
+ /*11734*/ uint16(x86_xSetOp), uint16(x86_FISUBR),
+ /*11736*/ uint16(x86_xArgM32int),
+ /*11737*/ uint16(x86_xMatch),
+ /*11738*/ uint16(x86_xSetOp), uint16(x86_FIDIV),
+ /*11740*/ uint16(x86_xArgM32int),
+ /*11741*/ uint16(x86_xMatch),
+ /*11742*/ uint16(x86_xSetOp), uint16(x86_FIDIVR),
+ /*11744*/ uint16(x86_xArgM32int),
+ /*11745*/ uint16(x86_xMatch),
+ /*11746*/ uint16(x86_xSetOp), uint16(x86_FCMOVB),
+ /*11748*/ uint16(x86_xArgST),
+ /*11749*/ uint16(x86_xArgSTi),
+ /*11750*/ uint16(x86_xMatch),
+ /*11751*/ uint16(x86_xSetOp), uint16(x86_FCMOVE),
+ /*11753*/ uint16(x86_xArgST),
+ /*11754*/ uint16(x86_xArgSTi),
+ /*11755*/ uint16(x86_xMatch),
+ /*11756*/ uint16(x86_xSetOp), uint16(x86_FCMOVBE),
+ /*11758*/ uint16(x86_xArgST),
+ /*11759*/ uint16(x86_xArgSTi),
+ /*11760*/ uint16(x86_xMatch),
+ /*11761*/ uint16(x86_xSetOp), uint16(x86_FCMOVU),
+ /*11763*/ uint16(x86_xArgST),
+ /*11764*/ uint16(x86_xArgSTi),
+ /*11765*/ uint16(x86_xMatch),
+ /*11766*/ uint16(x86_xSetOp), uint16(x86_FUCOMPP),
+ /*11768*/ uint16(x86_xMatch),
+ /*11769*/ uint16(x86_xCondByte), 50,
+ 0xc0, 11904,
+ 0xc1, 11904,
+ 0xc2, 11904,
+ 0xc3, 11904,
+ 0xc4, 11904,
+ 0xc5, 11904,
+ 0xc6, 11904,
+ 0xc7, 11904,
+ 0xc8, 11909,
+ 0xc9, 11909,
+ 0xca, 11909,
+ 0xcb, 11909,
+ 0xcc, 11909,
+ 0xcd, 11909,
+ 0xce, 11909,
+ 0xcf, 11909,
+ 0xd0, 11914,
+ 0xd1, 11914,
+ 0xd2, 11914,
+ 0xd3, 11914,
+ 0xd4, 11914,
+ 0xd5, 11914,
+ 0xd6, 11914,
+ 0xd7, 11914,
+ 0xd8, 11919,
+ 0xd9, 11919,
+ 0xda, 11919,
+ 0xdb, 11919,
+ 0xdc, 11919,
+ 0xdd, 11919,
+ 0xde, 11919,
+ 0xdf, 11919,
+ 0xE2, 11924,
+ 0xE3, 11927,
+ 0xe8, 11930,
+ 0xe9, 11930,
+ 0xea, 11930,
+ 0xeb, 11930,
+ 0xec, 11930,
+ 0xed, 11930,
+ 0xee, 11930,
+ 0xef, 11930,
+ 0xf0, 11935,
+ 0xf1, 11935,
+ 0xf2, 11935,
+ 0xf3, 11935,
+ 0xf4, 11935,
+ 0xf5, 11935,
+ 0xf6, 11935,
+ 0xf7, 11935,
+ /*11871*/ uint16(x86_xCondSlashR),
+ 11880, // 0
+ 11884, // 1
+ 11888, // 2
+ 11892, // 3
+ 0, // 4
+ 11896, // 5
+ 0, // 6
+ 11900, // 7
+ /*11880*/ uint16(x86_xSetOp), uint16(x86_FILD),
+ /*11882*/ uint16(x86_xArgM32int),
+ /*11883*/ uint16(x86_xMatch),
+ /*11884*/ uint16(x86_xSetOp), uint16(x86_FISTTP),
+ /*11886*/ uint16(x86_xArgM32int),
+ /*11887*/ uint16(x86_xMatch),
+ /*11888*/ uint16(x86_xSetOp), uint16(x86_FIST),
+ /*11890*/ uint16(x86_xArgM32int),
+ /*11891*/ uint16(x86_xMatch),
+ /*11892*/ uint16(x86_xSetOp), uint16(x86_FISTP),
+ /*11894*/ uint16(x86_xArgM32int),
+ /*11895*/ uint16(x86_xMatch),
+ /*11896*/ uint16(x86_xSetOp), uint16(x86_FLD),
+ /*11898*/ uint16(x86_xArgM80fp),
+ /*11899*/ uint16(x86_xMatch),
+ /*11900*/ uint16(x86_xSetOp), uint16(x86_FSTP),
+ /*11902*/ uint16(x86_xArgM80fp),
+ /*11903*/ uint16(x86_xMatch),
+ /*11904*/ uint16(x86_xSetOp), uint16(x86_FCMOVNB),
+ /*11906*/ uint16(x86_xArgST),
+ /*11907*/ uint16(x86_xArgSTi),
+ /*11908*/ uint16(x86_xMatch),
+ /*11909*/ uint16(x86_xSetOp), uint16(x86_FCMOVNE),
+ /*11911*/ uint16(x86_xArgST),
+ /*11912*/ uint16(x86_xArgSTi),
+ /*11913*/ uint16(x86_xMatch),
+ /*11914*/ uint16(x86_xSetOp), uint16(x86_FCMOVNBE),
+ /*11916*/ uint16(x86_xArgST),
+ /*11917*/ uint16(x86_xArgSTi),
+ /*11918*/ uint16(x86_xMatch),
+ /*11919*/ uint16(x86_xSetOp), uint16(x86_FCMOVNU),
+ /*11921*/ uint16(x86_xArgST),
+ /*11922*/ uint16(x86_xArgSTi),
+ /*11923*/ uint16(x86_xMatch),
+ /*11924*/ uint16(x86_xSetOp), uint16(x86_FNCLEX),
+ /*11926*/ uint16(x86_xMatch),
+ /*11927*/ uint16(x86_xSetOp), uint16(x86_FNINIT),
+ /*11929*/ uint16(x86_xMatch),
+ /*11930*/ uint16(x86_xSetOp), uint16(x86_FUCOMI),
+ /*11932*/ uint16(x86_xArgST),
+ /*11933*/ uint16(x86_xArgSTi),
+ /*11934*/ uint16(x86_xMatch),
+ /*11935*/ uint16(x86_xSetOp), uint16(x86_FCOMI),
+ /*11937*/ uint16(x86_xArgST),
+ /*11938*/ uint16(x86_xArgSTi),
+ /*11939*/ uint16(x86_xMatch),
+ /*11940*/ uint16(x86_xCondByte), 48,
+ 0xc0, 12079,
+ 0xc1, 12079,
+ 0xc2, 12079,
+ 0xc3, 12079,
+ 0xc4, 12079,
+ 0xc5, 12079,
+ 0xc6, 12079,
+ 0xc7, 12079,
+ 0xc8, 12084,
+ 0xc9, 12084,
+ 0xca, 12084,
+ 0xcb, 12084,
+ 0xcc, 12084,
+ 0xcd, 12084,
+ 0xce, 12084,
+ 0xcf, 12084,
+ 0xe0, 12089,
+ 0xe1, 12089,
+ 0xe2, 12089,
+ 0xe3, 12089,
+ 0xe4, 12089,
+ 0xe5, 12089,
+ 0xe6, 12089,
+ 0xe7, 12089,
+ 0xe8, 12094,
+ 0xe9, 12094,
+ 0xea, 12094,
+ 0xeb, 12094,
+ 0xec, 12094,
+ 0xed, 12094,
+ 0xee, 12094,
+ 0xef, 12094,
+ 0xf0, 12099,
+ 0xf1, 12099,
+ 0xf2, 12099,
+ 0xf3, 12099,
+ 0xf4, 12099,
+ 0xf5, 12099,
+ 0xf6, 12099,
+ 0xf7, 12099,
+ 0xf8, 12104,
+ 0xf9, 12104,
+ 0xfa, 12104,
+ 0xfb, 12104,
+ 0xfc, 12104,
+ 0xfd, 12104,
+ 0xfe, 12104,
+ 0xff, 12104,
+ /*12038*/ uint16(x86_xCondSlashR),
+ 12047, // 0
+ 12051, // 1
+ 12055, // 2
+ 12059, // 3
+ 12063, // 4
+ 12067, // 5
+ 12071, // 6
+ 12075, // 7
+ /*12047*/ uint16(x86_xSetOp), uint16(x86_FADD),
+ /*12049*/ uint16(x86_xArgM64fp),
+ /*12050*/ uint16(x86_xMatch),
+ /*12051*/ uint16(x86_xSetOp), uint16(x86_FMUL),
+ /*12053*/ uint16(x86_xArgM64fp),
+ /*12054*/ uint16(x86_xMatch),
+ /*12055*/ uint16(x86_xSetOp), uint16(x86_FCOM),
+ /*12057*/ uint16(x86_xArgM64fp),
+ /*12058*/ uint16(x86_xMatch),
+ /*12059*/ uint16(x86_xSetOp), uint16(x86_FCOMP),
+ /*12061*/ uint16(x86_xArgM64fp),
+ /*12062*/ uint16(x86_xMatch),
+ /*12063*/ uint16(x86_xSetOp), uint16(x86_FSUB),
+ /*12065*/ uint16(x86_xArgM64fp),
+ /*12066*/ uint16(x86_xMatch),
+ /*12067*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
+ /*12069*/ uint16(x86_xArgM64fp),
+ /*12070*/ uint16(x86_xMatch),
+ /*12071*/ uint16(x86_xSetOp), uint16(x86_FDIV),
+ /*12073*/ uint16(x86_xArgM64fp),
+ /*12074*/ uint16(x86_xMatch),
+ /*12075*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
+ /*12077*/ uint16(x86_xArgM64fp),
+ /*12078*/ uint16(x86_xMatch),
+ /*12079*/ uint16(x86_xSetOp), uint16(x86_FADD),
+ /*12081*/ uint16(x86_xArgSTi),
+ /*12082*/ uint16(x86_xArgST),
+ /*12083*/ uint16(x86_xMatch),
+ /*12084*/ uint16(x86_xSetOp), uint16(x86_FMUL),
+ /*12086*/ uint16(x86_xArgSTi),
+ /*12087*/ uint16(x86_xArgST),
+ /*12088*/ uint16(x86_xMatch),
+ /*12089*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
+ /*12091*/ uint16(x86_xArgSTi),
+ /*12092*/ uint16(x86_xArgST),
+ /*12093*/ uint16(x86_xMatch),
+ /*12094*/ uint16(x86_xSetOp), uint16(x86_FSUB),
+ /*12096*/ uint16(x86_xArgSTi),
+ /*12097*/ uint16(x86_xArgST),
+ /*12098*/ uint16(x86_xMatch),
+ /*12099*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
+ /*12101*/ uint16(x86_xArgSTi),
+ /*12102*/ uint16(x86_xArgST),
+ /*12103*/ uint16(x86_xMatch),
+ /*12104*/ uint16(x86_xSetOp), uint16(x86_FDIV),
+ /*12106*/ uint16(x86_xArgSTi),
+ /*12107*/ uint16(x86_xArgST),
+ /*12108*/ uint16(x86_xMatch),
+ /*12109*/ uint16(x86_xCondByte), 40,
+ 0xc0, 12228,
+ 0xc1, 12228,
+ 0xc2, 12228,
+ 0xc3, 12228,
+ 0xc4, 12228,
+ 0xc5, 12228,
+ 0xc6, 12228,
+ 0xc7, 12228,
+ 0xd0, 12232,
+ 0xd1, 12232,
+ 0xd2, 12232,
+ 0xd3, 12232,
+ 0xd4, 12232,
+ 0xd5, 12232,
+ 0xd6, 12232,
+ 0xd7, 12232,
+ 0xd8, 12236,
+ 0xd9, 12236,
+ 0xda, 12236,
+ 0xdb, 12236,
+ 0xdc, 12236,
+ 0xdd, 12236,
+ 0xde, 12236,
+ 0xdf, 12236,
+ 0xe0, 12240,
+ 0xe1, 12240,
+ 0xe2, 12240,
+ 0xe3, 12240,
+ 0xe4, 12240,
+ 0xe5, 12240,
+ 0xe6, 12240,
+ 0xe7, 12240,
+ 0xe8, 12244,
+ 0xe9, 12244,
+ 0xea, 12244,
+ 0xeb, 12244,
+ 0xec, 12244,
+ 0xed, 12244,
+ 0xee, 12244,
+ 0xef, 12244,
+ /*12191*/ uint16(x86_xCondSlashR),
+ 12200, // 0
+ 12204, // 1
+ 12208, // 2
+ 12212, // 3
+ 12216, // 4
+ 0, // 5
+ 12220, // 6
+ 12224, // 7
+ /*12200*/ uint16(x86_xSetOp), uint16(x86_FLD),
+ /*12202*/ uint16(x86_xArgM64fp),
+ /*12203*/ uint16(x86_xMatch),
+ /*12204*/ uint16(x86_xSetOp), uint16(x86_FISTTP),
+ /*12206*/ uint16(x86_xArgM64int),
+ /*12207*/ uint16(x86_xMatch),
+ /*12208*/ uint16(x86_xSetOp), uint16(x86_FST),
+ /*12210*/ uint16(x86_xArgM64fp),
+ /*12211*/ uint16(x86_xMatch),
+ /*12212*/ uint16(x86_xSetOp), uint16(x86_FSTP),
+ /*12214*/ uint16(x86_xArgM64fp),
+ /*12215*/ uint16(x86_xMatch),
+ /*12216*/ uint16(x86_xSetOp), uint16(x86_FRSTOR),
+ /*12218*/ uint16(x86_xArgM94108byte),
+ /*12219*/ uint16(x86_xMatch),
+ /*12220*/ uint16(x86_xSetOp), uint16(x86_FNSAVE),
+ /*12222*/ uint16(x86_xArgM94108byte),
+ /*12223*/ uint16(x86_xMatch),
+ /*12224*/ uint16(x86_xSetOp), uint16(x86_FNSTSW),
+ /*12226*/ uint16(x86_xArgM2byte),
+ /*12227*/ uint16(x86_xMatch),
+ /*12228*/ uint16(x86_xSetOp), uint16(x86_FFREE),
+ /*12230*/ uint16(x86_xArgSTi),
+ /*12231*/ uint16(x86_xMatch),
+ /*12232*/ uint16(x86_xSetOp), uint16(x86_FST),
+ /*12234*/ uint16(x86_xArgSTi),
+ /*12235*/ uint16(x86_xMatch),
+ /*12236*/ uint16(x86_xSetOp), uint16(x86_FSTP),
+ /*12238*/ uint16(x86_xArgSTi),
+ /*12239*/ uint16(x86_xMatch),
+ /*12240*/ uint16(x86_xSetOp), uint16(x86_FUCOM),
+ /*12242*/ uint16(x86_xArgSTi),
+ /*12243*/ uint16(x86_xMatch),
+ /*12244*/ uint16(x86_xSetOp), uint16(x86_FUCOMP),
+ /*12246*/ uint16(x86_xArgSTi),
+ /*12247*/ uint16(x86_xMatch),
+ /*12248*/ uint16(x86_xCondByte), 49,
+ 0xc0, 12389,
+ 0xc1, 12389,
+ 0xc2, 12389,
+ 0xc3, 12389,
+ 0xc4, 12389,
+ 0xc5, 12389,
+ 0xc6, 12389,
+ 0xc7, 12389,
+ 0xc8, 12394,
+ 0xc9, 12394,
+ 0xca, 12394,
+ 0xcb, 12394,
+ 0xcc, 12394,
+ 0xcd, 12394,
+ 0xce, 12394,
+ 0xcf, 12394,
+ 0xD9, 12399,
+ 0xe0, 12402,
+ 0xe1, 12402,
+ 0xe2, 12402,
+ 0xe3, 12402,
+ 0xe4, 12402,
+ 0xe5, 12402,
+ 0xe6, 12402,
+ 0xe7, 12402,
+ 0xe8, 12407,
+ 0xe9, 12407,
+ 0xea, 12407,
+ 0xeb, 12407,
+ 0xec, 12407,
+ 0xed, 12407,
+ 0xee, 12407,
+ 0xef, 12407,
+ 0xf0, 12412,
+ 0xf1, 12412,
+ 0xf2, 12412,
+ 0xf3, 12412,
+ 0xf4, 12412,
+ 0xf5, 12412,
+ 0xf6, 12412,
+ 0xf7, 12412,
+ 0xf8, 12417,
+ 0xf9, 12417,
+ 0xfa, 12417,
+ 0xfb, 12417,
+ 0xfc, 12417,
+ 0xfd, 12417,
+ 0xfe, 12417,
+ 0xff, 12417,
+ /*12348*/ uint16(x86_xCondSlashR),
+ 12357, // 0
+ 12361, // 1
+ 12365, // 2
+ 12369, // 3
+ 12373, // 4
+ 12377, // 5
+ 12381, // 6
+ 12385, // 7
+ /*12357*/ uint16(x86_xSetOp), uint16(x86_FIADD),
+ /*12359*/ uint16(x86_xArgM16int),
+ /*12360*/ uint16(x86_xMatch),
+ /*12361*/ uint16(x86_xSetOp), uint16(x86_FIMUL),
+ /*12363*/ uint16(x86_xArgM16int),
+ /*12364*/ uint16(x86_xMatch),
+ /*12365*/ uint16(x86_xSetOp), uint16(x86_FICOM),
+ /*12367*/ uint16(x86_xArgM16int),
+ /*12368*/ uint16(x86_xMatch),
+ /*12369*/ uint16(x86_xSetOp), uint16(x86_FICOMP),
+ /*12371*/ uint16(x86_xArgM16int),
+ /*12372*/ uint16(x86_xMatch),
+ /*12373*/ uint16(x86_xSetOp), uint16(x86_FISUB),
+ /*12375*/ uint16(x86_xArgM16int),
+ /*12376*/ uint16(x86_xMatch),
+ /*12377*/ uint16(x86_xSetOp), uint16(x86_FISUBR),
+ /*12379*/ uint16(x86_xArgM16int),
+ /*12380*/ uint16(x86_xMatch),
+ /*12381*/ uint16(x86_xSetOp), uint16(x86_FIDIV),
+ /*12383*/ uint16(x86_xArgM16int),
+ /*12384*/ uint16(x86_xMatch),
+ /*12385*/ uint16(x86_xSetOp), uint16(x86_FIDIVR),
+ /*12387*/ uint16(x86_xArgM16int),
+ /*12388*/ uint16(x86_xMatch),
+ /*12389*/ uint16(x86_xSetOp), uint16(x86_FADDP),
+ /*12391*/ uint16(x86_xArgSTi),
+ /*12392*/ uint16(x86_xArgST),
+ /*12393*/ uint16(x86_xMatch),
+ /*12394*/ uint16(x86_xSetOp), uint16(x86_FMULP),
+ /*12396*/ uint16(x86_xArgSTi),
+ /*12397*/ uint16(x86_xArgST),
+ /*12398*/ uint16(x86_xMatch),
+ /*12399*/ uint16(x86_xSetOp), uint16(x86_FCOMPP),
+ /*12401*/ uint16(x86_xMatch),
+ /*12402*/ uint16(x86_xSetOp), uint16(x86_FSUBRP),
+ /*12404*/ uint16(x86_xArgSTi),
+ /*12405*/ uint16(x86_xArgST),
+ /*12406*/ uint16(x86_xMatch),
+ /*12407*/ uint16(x86_xSetOp), uint16(x86_FSUBP),
+ /*12409*/ uint16(x86_xArgSTi),
+ /*12410*/ uint16(x86_xArgST),
+ /*12411*/ uint16(x86_xMatch),
+ /*12412*/ uint16(x86_xSetOp), uint16(x86_FDIVRP),
+ /*12414*/ uint16(x86_xArgSTi),
+ /*12415*/ uint16(x86_xArgST),
+ /*12416*/ uint16(x86_xMatch),
+ /*12417*/ uint16(x86_xSetOp), uint16(x86_FDIVP),
+ /*12419*/ uint16(x86_xArgSTi),
+ /*12420*/ uint16(x86_xArgST),
+ /*12421*/ uint16(x86_xMatch),
+ /*12422*/ uint16(x86_xCondByte), 25,
+ 0xc0, 12515,
+ 0xc1, 12515,
+ 0xc2, 12515,
+ 0xc3, 12515,
+ 0xc4, 12515,
+ 0xc5, 12515,
+ 0xc6, 12515,
+ 0xc7, 12515,
+ 0xE0, 12519,
+ 0xe8, 12523,
+ 0xe9, 12523,
+ 0xea, 12523,
+ 0xeb, 12523,
+ 0xec, 12523,
+ 0xed, 12523,
+ 0xee, 12523,
+ 0xef, 12523,
+ 0xf0, 12528,
+ 0xf1, 12528,
+ 0xf2, 12528,
+ 0xf3, 12528,
+ 0xf4, 12528,
+ 0xf5, 12528,
+ 0xf6, 12528,
+ 0xf7, 12528,
+ /*12474*/ uint16(x86_xCondSlashR),
+ 12483, // 0
+ 12487, // 1
+ 12491, // 2
+ 12495, // 3
+ 12499, // 4
+ 12503, // 5
+ 12507, // 6
+ 12511, // 7
+ /*12483*/ uint16(x86_xSetOp), uint16(x86_FILD),
+ /*12485*/ uint16(x86_xArgM16int),
+ /*12486*/ uint16(x86_xMatch),
+ /*12487*/ uint16(x86_xSetOp), uint16(x86_FISTTP),
+ /*12489*/ uint16(x86_xArgM16int),
+ /*12490*/ uint16(x86_xMatch),
+ /*12491*/ uint16(x86_xSetOp), uint16(x86_FIST),
+ /*12493*/ uint16(x86_xArgM16int),
+ /*12494*/ uint16(x86_xMatch),
+ /*12495*/ uint16(x86_xSetOp), uint16(x86_FISTP),
+ /*12497*/ uint16(x86_xArgM16int),
+ /*12498*/ uint16(x86_xMatch),
+ /*12499*/ uint16(x86_xSetOp), uint16(x86_FBLD),
+ /*12501*/ uint16(x86_xArgM80dec),
+ /*12502*/ uint16(x86_xMatch),
+ /*12503*/ uint16(x86_xSetOp), uint16(x86_FILD),
+ /*12505*/ uint16(x86_xArgM64int),
+ /*12506*/ uint16(x86_xMatch),
+ /*12507*/ uint16(x86_xSetOp), uint16(x86_FBSTP),
+ /*12509*/ uint16(x86_xArgM80bcd),
+ /*12510*/ uint16(x86_xMatch),
+ /*12511*/ uint16(x86_xSetOp), uint16(x86_FISTP),
+ /*12513*/ uint16(x86_xArgM64int),
+ /*12514*/ uint16(x86_xMatch),
+ /*12515*/ uint16(x86_xSetOp), uint16(x86_FFREEP),
+ /*12517*/ uint16(x86_xArgSTi),
+ /*12518*/ uint16(x86_xMatch),
+ /*12519*/ uint16(x86_xSetOp), uint16(x86_FNSTSW),
+ /*12521*/ uint16(x86_xArgAX),
+ /*12522*/ uint16(x86_xMatch),
+ /*12523*/ uint16(x86_xSetOp), uint16(x86_FUCOMIP),
+ /*12525*/ uint16(x86_xArgST),
+ /*12526*/ uint16(x86_xArgSTi),
+ /*12527*/ uint16(x86_xMatch),
+ /*12528*/ uint16(x86_xSetOp), uint16(x86_FCOMIP),
+ /*12530*/ uint16(x86_xArgST),
+ /*12531*/ uint16(x86_xArgSTi),
+ /*12532*/ uint16(x86_xMatch),
+ /*12533*/ uint16(x86_xSetOp), uint16(x86_LOOPNE),
+ /*12535*/ uint16(x86_xReadCb),
+ /*12536*/ uint16(x86_xArgRel8),
+ /*12537*/ uint16(x86_xMatch),
+ /*12538*/ uint16(x86_xSetOp), uint16(x86_LOOPE),
+ /*12540*/ uint16(x86_xReadCb),
+ /*12541*/ uint16(x86_xArgRel8),
+ /*12542*/ uint16(x86_xMatch),
+ /*12543*/ uint16(x86_xSetOp), uint16(x86_LOOP),
+ /*12545*/ uint16(x86_xReadCb),
+ /*12546*/ uint16(x86_xArgRel8),
+ /*12547*/ uint16(x86_xMatch),
+ /*12548*/ uint16(x86_xCondIs64), 12551, 12565,
+ /*12551*/ uint16(x86_xCondAddrSize), 12555, 12560, 0,
+ /*12555*/ uint16(x86_xSetOp), uint16(x86_JCXZ),
+ /*12557*/ uint16(x86_xReadCb),
+ /*12558*/ uint16(x86_xArgRel8),
+ /*12559*/ uint16(x86_xMatch),
+ /*12560*/ uint16(x86_xSetOp), uint16(x86_JECXZ),
+ /*12562*/ uint16(x86_xReadCb),
+ /*12563*/ uint16(x86_xArgRel8),
+ /*12564*/ uint16(x86_xMatch),
+ /*12565*/ uint16(x86_xCondAddrSize), 0, 12560, 12569,
+ /*12569*/ uint16(x86_xSetOp), uint16(x86_JRCXZ),
+ /*12571*/ uint16(x86_xReadCb),
+ /*12572*/ uint16(x86_xArgRel8),
+ /*12573*/ uint16(x86_xMatch),
+ /*12574*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12576*/ uint16(x86_xReadIb),
+ /*12577*/ uint16(x86_xArgAL),
+ /*12578*/ uint16(x86_xArgImm8u),
+ /*12579*/ uint16(x86_xMatch),
+ /*12580*/ uint16(x86_xCondDataSize), 12584, 12590, 12596,
+ /*12584*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12586*/ uint16(x86_xReadIb),
+ /*12587*/ uint16(x86_xArgAX),
+ /*12588*/ uint16(x86_xArgImm8u),
+ /*12589*/ uint16(x86_xMatch),
+ /*12590*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12592*/ uint16(x86_xReadIb),
+ /*12593*/ uint16(x86_xArgEAX),
+ /*12594*/ uint16(x86_xArgImm8u),
+ /*12595*/ uint16(x86_xMatch),
+ /*12596*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12598*/ uint16(x86_xReadIb),
+ /*12599*/ uint16(x86_xArgEAX),
+ /*12600*/ uint16(x86_xArgImm8u),
+ /*12601*/ uint16(x86_xMatch),
+ /*12602*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12604*/ uint16(x86_xReadIb),
+ /*12605*/ uint16(x86_xArgImm8u),
+ /*12606*/ uint16(x86_xArgAL),
+ /*12607*/ uint16(x86_xMatch),
+ /*12608*/ uint16(x86_xCondDataSize), 12612, 12618, 12624,
+ /*12612*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12614*/ uint16(x86_xReadIb),
+ /*12615*/ uint16(x86_xArgImm8u),
+ /*12616*/ uint16(x86_xArgAX),
+ /*12617*/ uint16(x86_xMatch),
+ /*12618*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12620*/ uint16(x86_xReadIb),
+ /*12621*/ uint16(x86_xArgImm8u),
+ /*12622*/ uint16(x86_xArgEAX),
+ /*12623*/ uint16(x86_xMatch),
+ /*12624*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12626*/ uint16(x86_xReadIb),
+ /*12627*/ uint16(x86_xArgImm8u),
+ /*12628*/ uint16(x86_xArgEAX),
+ /*12629*/ uint16(x86_xMatch),
+ /*12630*/ uint16(x86_xCondIs64), 12633, 12647,
+ /*12633*/ uint16(x86_xCondDataSize), 12637, 12642, 0,
+ /*12637*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*12639*/ uint16(x86_xReadCw),
+ /*12640*/ uint16(x86_xArgRel16),
+ /*12641*/ uint16(x86_xMatch),
+ /*12642*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*12644*/ uint16(x86_xReadCd),
+ /*12645*/ uint16(x86_xArgRel32),
+ /*12646*/ uint16(x86_xMatch),
+ /*12647*/ uint16(x86_xCondDataSize), 12651, 12642, 12656,
+ /*12651*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*12653*/ uint16(x86_xReadCd),
+ /*12654*/ uint16(x86_xArgRel32),
+ /*12655*/ uint16(x86_xMatch),
+ /*12656*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*12658*/ uint16(x86_xReadCd),
+ /*12659*/ uint16(x86_xArgRel32),
+ /*12660*/ uint16(x86_xMatch),
+ /*12661*/ uint16(x86_xCondIs64), 12664, 12678,
+ /*12664*/ uint16(x86_xCondDataSize), 12668, 12673, 0,
+ /*12668*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*12670*/ uint16(x86_xReadCw),
+ /*12671*/ uint16(x86_xArgRel16),
+ /*12672*/ uint16(x86_xMatch),
+ /*12673*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*12675*/ uint16(x86_xReadCd),
+ /*12676*/ uint16(x86_xArgRel32),
+ /*12677*/ uint16(x86_xMatch),
+ /*12678*/ uint16(x86_xCondDataSize), 12682, 12673, 12687,
+ /*12682*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*12684*/ uint16(x86_xReadCd),
+ /*12685*/ uint16(x86_xArgRel32),
+ /*12686*/ uint16(x86_xMatch),
+ /*12687*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*12689*/ uint16(x86_xReadCd),
+ /*12690*/ uint16(x86_xArgRel32),
+ /*12691*/ uint16(x86_xMatch),
+ /*12692*/ uint16(x86_xCondIs64), 12695, 0,
+ /*12695*/ uint16(x86_xCondDataSize), 12699, 12704, 0,
+ /*12699*/ uint16(x86_xSetOp), uint16(x86_LJMP),
+ /*12701*/ uint16(x86_xReadCd),
+ /*12702*/ uint16(x86_xArgPtr16colon16),
+ /*12703*/ uint16(x86_xMatch),
+ /*12704*/ uint16(x86_xSetOp), uint16(x86_LJMP),
+ /*12706*/ uint16(x86_xReadCp),
+ /*12707*/ uint16(x86_xArgPtr16colon32),
+ /*12708*/ uint16(x86_xMatch),
+ /*12709*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*12711*/ uint16(x86_xReadCb),
+ /*12712*/ uint16(x86_xArgRel8),
+ /*12713*/ uint16(x86_xMatch),
+ /*12714*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12716*/ uint16(x86_xArgAL),
+ /*12717*/ uint16(x86_xArgDX),
+ /*12718*/ uint16(x86_xMatch),
+ /*12719*/ uint16(x86_xCondDataSize), 12723, 12728, 12733,
+ /*12723*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12725*/ uint16(x86_xArgAX),
+ /*12726*/ uint16(x86_xArgDX),
+ /*12727*/ uint16(x86_xMatch),
+ /*12728*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12730*/ uint16(x86_xArgEAX),
+ /*12731*/ uint16(x86_xArgDX),
+ /*12732*/ uint16(x86_xMatch),
+ /*12733*/ uint16(x86_xSetOp), uint16(x86_IN),
+ /*12735*/ uint16(x86_xArgEAX),
+ /*12736*/ uint16(x86_xArgDX),
+ /*12737*/ uint16(x86_xMatch),
+ /*12738*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12740*/ uint16(x86_xArgDX),
+ /*12741*/ uint16(x86_xArgAL),
+ /*12742*/ uint16(x86_xMatch),
+ /*12743*/ uint16(x86_xCondDataSize), 12747, 12752, 12757,
+ /*12747*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12749*/ uint16(x86_xArgDX),
+ /*12750*/ uint16(x86_xArgAX),
+ /*12751*/ uint16(x86_xMatch),
+ /*12752*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12754*/ uint16(x86_xArgDX),
+ /*12755*/ uint16(x86_xArgEAX),
+ /*12756*/ uint16(x86_xMatch),
+ /*12757*/ uint16(x86_xSetOp), uint16(x86_OUT),
+ /*12759*/ uint16(x86_xArgDX),
+ /*12760*/ uint16(x86_xArgEAX),
+ /*12761*/ uint16(x86_xMatch),
+ /*12762*/ uint16(x86_xSetOp), uint16(x86_ICEBP),
+ /*12764*/ uint16(x86_xMatch),
+ /*12765*/ uint16(x86_xSetOp), uint16(x86_HLT),
+ /*12767*/ uint16(x86_xMatch),
+ /*12768*/ uint16(x86_xSetOp), uint16(x86_CMC),
+ /*12770*/ uint16(x86_xMatch),
+ /*12771*/ uint16(x86_xCondSlashR),
+ 12780, // 0
+ 0, // 1
+ 12786, // 2
+ 12790, // 3
+ 12794, // 4
+ 12798, // 5
+ 12802, // 6
+ 12806, // 7
+ /*12780*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*12782*/ uint16(x86_xReadIb),
+ /*12783*/ uint16(x86_xArgRM8),
+ /*12784*/ uint16(x86_xArgImm8u),
+ /*12785*/ uint16(x86_xMatch),
+ /*12786*/ uint16(x86_xSetOp), uint16(x86_NOT),
+ /*12788*/ uint16(x86_xArgRM8),
+ /*12789*/ uint16(x86_xMatch),
+ /*12790*/ uint16(x86_xSetOp), uint16(x86_NEG),
+ /*12792*/ uint16(x86_xArgRM8),
+ /*12793*/ uint16(x86_xMatch),
+ /*12794*/ uint16(x86_xSetOp), uint16(x86_MUL),
+ /*12796*/ uint16(x86_xArgRM8),
+ /*12797*/ uint16(x86_xMatch),
+ /*12798*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*12800*/ uint16(x86_xArgRM8),
+ /*12801*/ uint16(x86_xMatch),
+ /*12802*/ uint16(x86_xSetOp), uint16(x86_DIV),
+ /*12804*/ uint16(x86_xArgRM8),
+ /*12805*/ uint16(x86_xMatch),
+ /*12806*/ uint16(x86_xSetOp), uint16(x86_IDIV),
+ /*12808*/ uint16(x86_xArgRM8),
+ /*12809*/ uint16(x86_xMatch),
+ /*12810*/ uint16(x86_xCondSlashR),
+ 12819, // 0
+ 0, // 1
+ 12848, // 2
+ 12871, // 3
+ 12894, // 4
+ 12917, // 5
+ 12940, // 6
+ 12963, // 7
+ /*12819*/ uint16(x86_xCondIs64), 12822, 12838,
+ /*12822*/ uint16(x86_xCondDataSize), 12826, 12832, 0,
+ /*12826*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*12828*/ uint16(x86_xReadIw),
+ /*12829*/ uint16(x86_xArgRM16),
+ /*12830*/ uint16(x86_xArgImm16),
+ /*12831*/ uint16(x86_xMatch),
+ /*12832*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*12834*/ uint16(x86_xReadId),
+ /*12835*/ uint16(x86_xArgRM32),
+ /*12836*/ uint16(x86_xArgImm32),
+ /*12837*/ uint16(x86_xMatch),
+ /*12838*/ uint16(x86_xCondDataSize), 12826, 12832, 12842,
+ /*12842*/ uint16(x86_xSetOp), uint16(x86_TEST),
+ /*12844*/ uint16(x86_xReadId),
+ /*12845*/ uint16(x86_xArgRM64),
+ /*12846*/ uint16(x86_xArgImm32),
+ /*12847*/ uint16(x86_xMatch),
+ /*12848*/ uint16(x86_xCondIs64), 12851, 12863,
+ /*12851*/ uint16(x86_xCondDataSize), 12855, 12859, 0,
+ /*12855*/ uint16(x86_xSetOp), uint16(x86_NOT),
+ /*12857*/ uint16(x86_xArgRM16),
+ /*12858*/ uint16(x86_xMatch),
+ /*12859*/ uint16(x86_xSetOp), uint16(x86_NOT),
+ /*12861*/ uint16(x86_xArgRM32),
+ /*12862*/ uint16(x86_xMatch),
+ /*12863*/ uint16(x86_xCondDataSize), 12855, 12859, 12867,
+ /*12867*/ uint16(x86_xSetOp), uint16(x86_NOT),
+ /*12869*/ uint16(x86_xArgRM64),
+ /*12870*/ uint16(x86_xMatch),
+ /*12871*/ uint16(x86_xCondIs64), 12874, 12886,
+ /*12874*/ uint16(x86_xCondDataSize), 12878, 12882, 0,
+ /*12878*/ uint16(x86_xSetOp), uint16(x86_NEG),
+ /*12880*/ uint16(x86_xArgRM16),
+ /*12881*/ uint16(x86_xMatch),
+ /*12882*/ uint16(x86_xSetOp), uint16(x86_NEG),
+ /*12884*/ uint16(x86_xArgRM32),
+ /*12885*/ uint16(x86_xMatch),
+ /*12886*/ uint16(x86_xCondDataSize), 12878, 12882, 12890,
+ /*12890*/ uint16(x86_xSetOp), uint16(x86_NEG),
+ /*12892*/ uint16(x86_xArgRM64),
+ /*12893*/ uint16(x86_xMatch),
+ /*12894*/ uint16(x86_xCondIs64), 12897, 12909,
+ /*12897*/ uint16(x86_xCondDataSize), 12901, 12905, 0,
+ /*12901*/ uint16(x86_xSetOp), uint16(x86_MUL),
+ /*12903*/ uint16(x86_xArgRM16),
+ /*12904*/ uint16(x86_xMatch),
+ /*12905*/ uint16(x86_xSetOp), uint16(x86_MUL),
+ /*12907*/ uint16(x86_xArgRM32),
+ /*12908*/ uint16(x86_xMatch),
+ /*12909*/ uint16(x86_xCondDataSize), 12901, 12905, 12913,
+ /*12913*/ uint16(x86_xSetOp), uint16(x86_MUL),
+ /*12915*/ uint16(x86_xArgRM64),
+ /*12916*/ uint16(x86_xMatch),
+ /*12917*/ uint16(x86_xCondIs64), 12920, 12932,
+ /*12920*/ uint16(x86_xCondDataSize), 12924, 12928, 0,
+ /*12924*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*12926*/ uint16(x86_xArgRM16),
+ /*12927*/ uint16(x86_xMatch),
+ /*12928*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*12930*/ uint16(x86_xArgRM32),
+ /*12931*/ uint16(x86_xMatch),
+ /*12932*/ uint16(x86_xCondDataSize), 12924, 12928, 12936,
+ /*12936*/ uint16(x86_xSetOp), uint16(x86_IMUL),
+ /*12938*/ uint16(x86_xArgRM64),
+ /*12939*/ uint16(x86_xMatch),
+ /*12940*/ uint16(x86_xCondIs64), 12943, 12955,
+ /*12943*/ uint16(x86_xCondDataSize), 12947, 12951, 0,
+ /*12947*/ uint16(x86_xSetOp), uint16(x86_DIV),
+ /*12949*/ uint16(x86_xArgRM16),
+ /*12950*/ uint16(x86_xMatch),
+ /*12951*/ uint16(x86_xSetOp), uint16(x86_DIV),
+ /*12953*/ uint16(x86_xArgRM32),
+ /*12954*/ uint16(x86_xMatch),
+ /*12955*/ uint16(x86_xCondDataSize), 12947, 12951, 12959,
+ /*12959*/ uint16(x86_xSetOp), uint16(x86_DIV),
+ /*12961*/ uint16(x86_xArgRM64),
+ /*12962*/ uint16(x86_xMatch),
+ /*12963*/ uint16(x86_xCondIs64), 12966, 12978,
+ /*12966*/ uint16(x86_xCondDataSize), 12970, 12974, 0,
+ /*12970*/ uint16(x86_xSetOp), uint16(x86_IDIV),
+ /*12972*/ uint16(x86_xArgRM16),
+ /*12973*/ uint16(x86_xMatch),
+ /*12974*/ uint16(x86_xSetOp), uint16(x86_IDIV),
+ /*12976*/ uint16(x86_xArgRM32),
+ /*12977*/ uint16(x86_xMatch),
+ /*12978*/ uint16(x86_xCondDataSize), 12970, 12974, 12982,
+ /*12982*/ uint16(x86_xSetOp), uint16(x86_IDIV),
+ /*12984*/ uint16(x86_xArgRM64),
+ /*12985*/ uint16(x86_xMatch),
+ /*12986*/ uint16(x86_xSetOp), uint16(x86_CLC),
+ /*12988*/ uint16(x86_xMatch),
+ /*12989*/ uint16(x86_xSetOp), uint16(x86_STC),
+ /*12991*/ uint16(x86_xMatch),
+ /*12992*/ uint16(x86_xSetOp), uint16(x86_CLI),
+ /*12994*/ uint16(x86_xMatch),
+ /*12995*/ uint16(x86_xSetOp), uint16(x86_STI),
+ /*12997*/ uint16(x86_xMatch),
+ /*12998*/ uint16(x86_xSetOp), uint16(x86_CLD),
+ /*13000*/ uint16(x86_xMatch),
+ /*13001*/ uint16(x86_xSetOp), uint16(x86_STD),
+ /*13003*/ uint16(x86_xMatch),
+ /*13004*/ uint16(x86_xCondSlashR),
+ 13013, // 0
+ 13017, // 1
+ 0, // 2
+ 0, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ /*13013*/ uint16(x86_xSetOp), uint16(x86_INC),
+ /*13015*/ uint16(x86_xArgRM8),
+ /*13016*/ uint16(x86_xMatch),
+ /*13017*/ uint16(x86_xSetOp), uint16(x86_DEC),
+ /*13019*/ uint16(x86_xArgRM8),
+ /*13020*/ uint16(x86_xMatch),
+ /*13021*/ uint16(x86_xCondSlashR),
+ 13030, // 0
+ 13053, // 1
+ 13076, // 2
+ 13095, // 3
+ 13118, // 4
+ 13137, // 5
+ 13160, // 6
+ 0, // 7
+ /*13030*/ uint16(x86_xCondIs64), 13033, 13045,
+ /*13033*/ uint16(x86_xCondDataSize), 13037, 13041, 0,
+ /*13037*/ uint16(x86_xSetOp), uint16(x86_INC),
+ /*13039*/ uint16(x86_xArgRM16),
+ /*13040*/ uint16(x86_xMatch),
+ /*13041*/ uint16(x86_xSetOp), uint16(x86_INC),
+ /*13043*/ uint16(x86_xArgRM32),
+ /*13044*/ uint16(x86_xMatch),
+ /*13045*/ uint16(x86_xCondDataSize), 13037, 13041, 13049,
+ /*13049*/ uint16(x86_xSetOp), uint16(x86_INC),
+ /*13051*/ uint16(x86_xArgRM64),
+ /*13052*/ uint16(x86_xMatch),
+ /*13053*/ uint16(x86_xCondIs64), 13056, 13068,
+ /*13056*/ uint16(x86_xCondDataSize), 13060, 13064, 0,
+ /*13060*/ uint16(x86_xSetOp), uint16(x86_DEC),
+ /*13062*/ uint16(x86_xArgRM16),
+ /*13063*/ uint16(x86_xMatch),
+ /*13064*/ uint16(x86_xSetOp), uint16(x86_DEC),
+ /*13066*/ uint16(x86_xArgRM32),
+ /*13067*/ uint16(x86_xMatch),
+ /*13068*/ uint16(x86_xCondDataSize), 13060, 13064, 13072,
+ /*13072*/ uint16(x86_xSetOp), uint16(x86_DEC),
+ /*13074*/ uint16(x86_xArgRM64),
+ /*13075*/ uint16(x86_xMatch),
+ /*13076*/ uint16(x86_xCondIs64), 13079, 13091,
+ /*13079*/ uint16(x86_xCondDataSize), 13083, 13087, 0,
+ /*13083*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*13085*/ uint16(x86_xArgRM16),
+ /*13086*/ uint16(x86_xMatch),
+ /*13087*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*13089*/ uint16(x86_xArgRM32),
+ /*13090*/ uint16(x86_xMatch),
+ /*13091*/ uint16(x86_xSetOp), uint16(x86_CALL),
+ /*13093*/ uint16(x86_xArgRM64),
+ /*13094*/ uint16(x86_xMatch),
+ /*13095*/ uint16(x86_xCondIs64), 13098, 13110,
+ /*13098*/ uint16(x86_xCondDataSize), 13102, 13106, 0,
+ /*13102*/ uint16(x86_xSetOp), uint16(x86_LCALL),
+ /*13104*/ uint16(x86_xArgM16colon16),
+ /*13105*/ uint16(x86_xMatch),
+ /*13106*/ uint16(x86_xSetOp), uint16(x86_LCALL),
+ /*13108*/ uint16(x86_xArgM16colon32),
+ /*13109*/ uint16(x86_xMatch),
+ /*13110*/ uint16(x86_xCondDataSize), 13102, 13106, 13114,
+ /*13114*/ uint16(x86_xSetOp), uint16(x86_LCALL),
+ /*13116*/ uint16(x86_xArgM16colon64),
+ /*13117*/ uint16(x86_xMatch),
+ /*13118*/ uint16(x86_xCondIs64), 13121, 13133,
+ /*13121*/ uint16(x86_xCondDataSize), 13125, 13129, 0,
+ /*13125*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*13127*/ uint16(x86_xArgRM16),
+ /*13128*/ uint16(x86_xMatch),
+ /*13129*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*13131*/ uint16(x86_xArgRM32),
+ /*13132*/ uint16(x86_xMatch),
+ /*13133*/ uint16(x86_xSetOp), uint16(x86_JMP),
+ /*13135*/ uint16(x86_xArgRM64),
+ /*13136*/ uint16(x86_xMatch),
+ /*13137*/ uint16(x86_xCondIs64), 13140, 13152,
+ /*13140*/ uint16(x86_xCondDataSize), 13144, 13148, 0,
+ /*13144*/ uint16(x86_xSetOp), uint16(x86_LJMP),
+ /*13146*/ uint16(x86_xArgM16colon16),
+ /*13147*/ uint16(x86_xMatch),
+ /*13148*/ uint16(x86_xSetOp), uint16(x86_LJMP),
+ /*13150*/ uint16(x86_xArgM16colon32),
+ /*13151*/ uint16(x86_xMatch),
+ /*13152*/ uint16(x86_xCondDataSize), 13144, 13148, 13156,
+ /*13156*/ uint16(x86_xSetOp), uint16(x86_LJMP),
+ /*13158*/ uint16(x86_xArgM16colon64),
+ /*13159*/ uint16(x86_xMatch),
+ /*13160*/ uint16(x86_xCondIs64), 13163, 13175,
+ /*13163*/ uint16(x86_xCondDataSize), 13167, 13171, 0,
+ /*13167*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*13169*/ uint16(x86_xArgRM16),
+ /*13170*/ uint16(x86_xMatch),
+ /*13171*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*13173*/ uint16(x86_xArgRM32),
+ /*13174*/ uint16(x86_xMatch),
+ /*13175*/ uint16(x86_xCondDataSize), 13167, 13179, 13183,
+ /*13179*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*13181*/ uint16(x86_xArgRM64),
+ /*13182*/ uint16(x86_xMatch),
+ /*13183*/ uint16(x86_xSetOp), uint16(x86_PUSH),
+ /*13185*/ uint16(x86_xArgRM64),
+ /*13186*/ uint16(x86_xMatch),
+}
+
+const (
+ _ x86_Op = iota
+
+ x86_AAA
+ x86_AAD
+ x86_AAM
+ x86_AAS
+ x86_ADC
+ x86_ADD
+ x86_ADDPD
+ x86_ADDPS
+ x86_ADDSD
+ x86_ADDSS
+ x86_ADDSUBPD
+ x86_ADDSUBPS
+ x86_AESDEC
+ x86_AESDECLAST
+ x86_AESENC
+ x86_AESENCLAST
+ x86_AESIMC
+ x86_AESKEYGENASSIST
+ x86_AND
+ x86_ANDNPD
+ x86_ANDNPS
+ x86_ANDPD
+ x86_ANDPS
+ x86_ARPL
+ x86_BLENDPD
+ x86_BLENDPS
+ x86_BLENDVPD
+ x86_BLENDVPS
+ x86_BOUND
+ x86_BSF
+ x86_BSR
+ x86_BSWAP
+ x86_BT
+ x86_BTC
+ x86_BTR
+ x86_BTS
+ x86_CALL
+ x86_CBW
+ x86_CDQ
+ x86_CDQE
+ x86_CLC
+ x86_CLD
+ x86_CLFLUSH
+ x86_CLI
+ x86_CLTS
+ x86_CMC
+ x86_CMOVA
+ x86_CMOVAE
+ x86_CMOVB
+ x86_CMOVBE
+ x86_CMOVE
+ x86_CMOVG
+ x86_CMOVGE
+ x86_CMOVL
+ x86_CMOVLE
+ x86_CMOVNE
+ x86_CMOVNO
+ x86_CMOVNP
+ x86_CMOVNS
+ x86_CMOVO
+ x86_CMOVP
+ x86_CMOVS
+ x86_CMP
+ x86_CMPPD
+ x86_CMPPS
+ x86_CMPSB
+ x86_CMPSD
+ x86_CMPSD_XMM
+ x86_CMPSQ
+ x86_CMPSS
+ x86_CMPSW
+ x86_CMPXCHG
+ x86_CMPXCHG16B
+ x86_CMPXCHG8B
+ x86_COMISD
+ x86_COMISS
+ x86_CPUID
+ x86_CQO
+ x86_CRC32
+ x86_CVTDQ2PD
+ x86_CVTDQ2PS
+ x86_CVTPD2DQ
+ x86_CVTPD2PI
+ x86_CVTPD2PS
+ x86_CVTPI2PD
+ x86_CVTPI2PS
+ x86_CVTPS2DQ
+ x86_CVTPS2PD
+ x86_CVTPS2PI
+ x86_CVTSD2SI
+ x86_CVTSD2SS
+ x86_CVTSI2SD
+ x86_CVTSI2SS
+ x86_CVTSS2SD
+ x86_CVTSS2SI
+ x86_CVTTPD2DQ
+ x86_CVTTPD2PI
+ x86_CVTTPS2DQ
+ x86_CVTTPS2PI
+ x86_CVTTSD2SI
+ x86_CVTTSS2SI
+ x86_CWD
+ x86_CWDE
+ x86_DAA
+ x86_DAS
+ x86_DEC
+ x86_DIV
+ x86_DIVPD
+ x86_DIVPS
+ x86_DIVSD
+ x86_DIVSS
+ x86_DPPD
+ x86_DPPS
+ x86_EMMS
+ x86_ENTER
+ x86_EXTRACTPS
+ x86_F2XM1
+ x86_FABS
+ x86_FADD
+ x86_FADDP
+ x86_FBLD
+ x86_FBSTP
+ x86_FCHS
+ x86_FCMOVB
+ x86_FCMOVBE
+ x86_FCMOVE
+ x86_FCMOVNB
+ x86_FCMOVNBE
+ x86_FCMOVNE
+ x86_FCMOVNU
+ x86_FCMOVU
+ x86_FCOM
+ x86_FCOMI
+ x86_FCOMIP
+ x86_FCOMP
+ x86_FCOMPP
+ x86_FCOS
+ x86_FDECSTP
+ x86_FDIV
+ x86_FDIVP
+ x86_FDIVR
+ x86_FDIVRP
+ x86_FFREE
+ x86_FFREEP
+ x86_FIADD
+ x86_FICOM
+ x86_FICOMP
+ x86_FIDIV
+ x86_FIDIVR
+ x86_FILD
+ x86_FIMUL
+ x86_FINCSTP
+ x86_FIST
+ x86_FISTP
+ x86_FISTTP
+ x86_FISUB
+ x86_FISUBR
+ x86_FLD
+ x86_FLD1
+ x86_FLDCW
+ x86_FLDENV
+ x86_FLDL2E
+ x86_FLDL2T
+ x86_FLDLG2
+ x86_FLDPI
+ x86_FMUL
+ x86_FMULP
+ x86_FNCLEX
+ x86_FNINIT
+ x86_FNOP
+ x86_FNSAVE
+ x86_FNSTCW
+ x86_FNSTENV
+ x86_FNSTSW
+ x86_FPATAN
+ x86_FPREM
+ x86_FPREM1
+ x86_FPTAN
+ x86_FRNDINT
+ x86_FRSTOR
+ x86_FSCALE
+ x86_FSIN
+ x86_FSINCOS
+ x86_FSQRT
+ x86_FST
+ x86_FSTP
+ x86_FSUB
+ x86_FSUBP
+ x86_FSUBR
+ x86_FSUBRP
+ x86_FTST
+ x86_FUCOM
+ x86_FUCOMI
+ x86_FUCOMIP
+ x86_FUCOMP
+ x86_FUCOMPP
+ x86_FWAIT
+ x86_FXAM
+ x86_FXCH
+ x86_FXRSTOR
+ x86_FXRSTOR64
+ x86_FXSAVE
+ x86_FXSAVE64
+ x86_FXTRACT
+ x86_FYL2X
+ x86_FYL2XP1
+ x86_HADDPD
+ x86_HADDPS
+ x86_HLT
+ x86_HSUBPD
+ x86_HSUBPS
+ x86_ICEBP
+ x86_IDIV
+ x86_IMUL
+ x86_IN
+ x86_INC
+ x86_INSB
+ x86_INSD
+ x86_INSERTPS
+ x86_INSW
+ x86_INT
+ x86_INTO
+ x86_INVD
+ x86_INVLPG
+ x86_INVPCID
+ x86_IRET
+ x86_IRETD
+ x86_IRETQ
+ x86_JA
+ x86_JAE
+ x86_JB
+ x86_JBE
+ x86_JCXZ
+ x86_JE
+ x86_JECXZ
+ x86_JG
+ x86_JGE
+ x86_JL
+ x86_JLE
+ x86_JMP
+ x86_JNE
+ x86_JNO
+ x86_JNP
+ x86_JNS
+ x86_JO
+ x86_JP
+ x86_JRCXZ
+ x86_JS
+ x86_LAHF
+ x86_LAR
+ x86_LCALL
+ x86_LDDQU
+ x86_LDMXCSR
+ x86_LDS
+ x86_LEA
+ x86_LEAVE
+ x86_LES
+ x86_LFENCE
+ x86_LFS
+ x86_LGDT
+ x86_LGS
+ x86_LIDT
+ x86_LJMP
+ x86_LLDT
+ x86_LMSW
+ x86_LODSB
+ x86_LODSD
+ x86_LODSQ
+ x86_LODSW
+ x86_LOOP
+ x86_LOOPE
+ x86_LOOPNE
+ x86_LRET
+ x86_LSL
+ x86_LSS
+ x86_LTR
+ x86_LZCNT
+ x86_MASKMOVDQU
+ x86_MASKMOVQ
+ x86_MAXPD
+ x86_MAXPS
+ x86_MAXSD
+ x86_MAXSS
+ x86_MFENCE
+ x86_MINPD
+ x86_MINPS
+ x86_MINSD
+ x86_MINSS
+ x86_MONITOR
+ x86_MOV
+ x86_MOVAPD
+ x86_MOVAPS
+ x86_MOVBE
+ x86_MOVD
+ x86_MOVDDUP
+ x86_MOVDQ2Q
+ x86_MOVDQA
+ x86_MOVDQU
+ x86_MOVHLPS
+ x86_MOVHPD
+ x86_MOVHPS
+ x86_MOVLHPS
+ x86_MOVLPD
+ x86_MOVLPS
+ x86_MOVMSKPD
+ x86_MOVMSKPS
+ x86_MOVNTDQ
+ x86_MOVNTDQA
+ x86_MOVNTI
+ x86_MOVNTPD
+ x86_MOVNTPS
+ x86_MOVNTQ
+ x86_MOVNTSD
+ x86_MOVNTSS
+ x86_MOVQ
+ x86_MOVQ2DQ
+ x86_MOVSB
+ x86_MOVSD
+ x86_MOVSD_XMM
+ x86_MOVSHDUP
+ x86_MOVSLDUP
+ x86_MOVSQ
+ x86_MOVSS
+ x86_MOVSW
+ x86_MOVSX
+ x86_MOVSXD
+ x86_MOVUPD
+ x86_MOVUPS
+ x86_MOVZX
+ x86_MPSADBW
+ x86_MUL
+ x86_MULPD
+ x86_MULPS
+ x86_MULSD
+ x86_MULSS
+ x86_MWAIT
+ x86_NEG
+ x86_NOP
+ x86_NOT
+ x86_OR
+ x86_ORPD
+ x86_ORPS
+ x86_OUT
+ x86_OUTSB
+ x86_OUTSD
+ x86_OUTSW
+ x86_PABSB
+ x86_PABSD
+ x86_PABSW
+ x86_PACKSSDW
+ x86_PACKSSWB
+ x86_PACKUSDW
+ x86_PACKUSWB
+ x86_PADDB
+ x86_PADDD
+ x86_PADDQ
+ x86_PADDSB
+ x86_PADDSW
+ x86_PADDUSB
+ x86_PADDUSW
+ x86_PADDW
+ x86_PALIGNR
+ x86_PAND
+ x86_PANDN
+ x86_PAUSE
+ x86_PAVGB
+ x86_PAVGW
+ x86_PBLENDVB
+ x86_PBLENDW
+ x86_PCLMULQDQ
+ x86_PCMPEQB
+ x86_PCMPEQD
+ x86_PCMPEQQ
+ x86_PCMPEQW
+ x86_PCMPESTRI
+ x86_PCMPESTRM
+ x86_PCMPGTB
+ x86_PCMPGTD
+ x86_PCMPGTQ
+ x86_PCMPGTW
+ x86_PCMPISTRI
+ x86_PCMPISTRM
+ x86_PEXTRB
+ x86_PEXTRD
+ x86_PEXTRQ
+ x86_PEXTRW
+ x86_PHADDD
+ x86_PHADDSW
+ x86_PHADDW
+ x86_PHMINPOSUW
+ x86_PHSUBD
+ x86_PHSUBSW
+ x86_PHSUBW
+ x86_PINSRB
+ x86_PINSRD
+ x86_PINSRQ
+ x86_PINSRW
+ x86_PMADDUBSW
+ x86_PMADDWD
+ x86_PMAXSB
+ x86_PMAXSD
+ x86_PMAXSW
+ x86_PMAXUB
+ x86_PMAXUD
+ x86_PMAXUW
+ x86_PMINSB
+ x86_PMINSD
+ x86_PMINSW
+ x86_PMINUB
+ x86_PMINUD
+ x86_PMINUW
+ x86_PMOVMSKB
+ x86_PMOVSXBD
+ x86_PMOVSXBQ
+ x86_PMOVSXBW
+ x86_PMOVSXDQ
+ x86_PMOVSXWD
+ x86_PMOVSXWQ
+ x86_PMOVZXBD
+ x86_PMOVZXBQ
+ x86_PMOVZXBW
+ x86_PMOVZXDQ
+ x86_PMOVZXWD
+ x86_PMOVZXWQ
+ x86_PMULDQ
+ x86_PMULHRSW
+ x86_PMULHUW
+ x86_PMULHW
+ x86_PMULLD
+ x86_PMULLW
+ x86_PMULUDQ
+ x86_POP
+ x86_POPA
+ x86_POPAD
+ x86_POPCNT
+ x86_POPF
+ x86_POPFD
+ x86_POPFQ
+ x86_POR
+ x86_PREFETCHNTA
+ x86_PREFETCHT0
+ x86_PREFETCHT1
+ x86_PREFETCHT2
+ x86_PREFETCHW
+ x86_PSADBW
+ x86_PSHUFB
+ x86_PSHUFD
+ x86_PSHUFHW
+ x86_PSHUFLW
+ x86_PSHUFW
+ x86_PSIGNB
+ x86_PSIGND
+ x86_PSIGNW
+ x86_PSLLD
+ x86_PSLLDQ
+ x86_PSLLQ
+ x86_PSLLW
+ x86_PSRAD
+ x86_PSRAW
+ x86_PSRLD
+ x86_PSRLDQ
+ x86_PSRLQ
+ x86_PSRLW
+ x86_PSUBB
+ x86_PSUBD
+ x86_PSUBQ
+ x86_PSUBSB
+ x86_PSUBSW
+ x86_PSUBUSB
+ x86_PSUBUSW
+ x86_PSUBW
+ x86_PTEST
+ x86_PUNPCKHBW
+ x86_PUNPCKHDQ
+ x86_PUNPCKHQDQ
+ x86_PUNPCKHWD
+ x86_PUNPCKLBW
+ x86_PUNPCKLDQ
+ x86_PUNPCKLQDQ
+ x86_PUNPCKLWD
+ x86_PUSH
+ x86_PUSHA
+ x86_PUSHAD
+ x86_PUSHF
+ x86_PUSHFD
+ x86_PUSHFQ
+ x86_PXOR
+ x86_RCL
+ x86_RCPPS
+ x86_RCPSS
+ x86_RCR
+ x86_RDFSBASE
+ x86_RDGSBASE
+ x86_RDMSR
+ x86_RDPMC
+ x86_RDRAND
+ x86_RDTSC
+ x86_RDTSCP
+ x86_RET
+ x86_ROL
+ x86_ROR
+ x86_ROUNDPD
+ x86_ROUNDPS
+ x86_ROUNDSD
+ x86_ROUNDSS
+ x86_RSM
+ x86_RSQRTPS
+ x86_RSQRTSS
+ x86_SAHF
+ x86_SAR
+ x86_SBB
+ x86_SCASB
+ x86_SCASD
+ x86_SCASQ
+ x86_SCASW
+ x86_SETA
+ x86_SETAE
+ x86_SETB
+ x86_SETBE
+ x86_SETE
+ x86_SETG
+ x86_SETGE
+ x86_SETL
+ x86_SETLE
+ x86_SETNE
+ x86_SETNO
+ x86_SETNP
+ x86_SETNS
+ x86_SETO
+ x86_SETP
+ x86_SETS
+ x86_SFENCE
+ x86_SGDT
+ x86_SHL
+ x86_SHLD
+ x86_SHR
+ x86_SHRD
+ x86_SHUFPD
+ x86_SHUFPS
+ x86_SIDT
+ x86_SLDT
+ x86_SMSW
+ x86_SQRTPD
+ x86_SQRTPS
+ x86_SQRTSD
+ x86_SQRTSS
+ x86_STC
+ x86_STD
+ x86_STI
+ x86_STMXCSR
+ x86_STOSB
+ x86_STOSD
+ x86_STOSQ
+ x86_STOSW
+ x86_STR
+ x86_SUB
+ x86_SUBPD
+ x86_SUBPS
+ x86_SUBSD
+ x86_SUBSS
+ x86_SWAPGS
+ x86_SYSCALL
+ x86_SYSENTER
+ x86_SYSEXIT
+ x86_SYSRET
+ x86_TEST
+ x86_TZCNT
+ x86_UCOMISD
+ x86_UCOMISS
+ x86_UD1
+ x86_UD2
+ x86_UNPCKHPD
+ x86_UNPCKHPS
+ x86_UNPCKLPD
+ x86_UNPCKLPS
+ x86_VERR
+ x86_VERW
+ x86_WBINVD
+ x86_WRFSBASE
+ x86_WRGSBASE
+ x86_WRMSR
+ x86_XABORT
+ x86_XADD
+ x86_XBEGIN
+ x86_XCHG
+ x86_XEND
+ x86_XGETBV
+ x86_XLATB
+ x86_XOR
+ x86_XORPD
+ x86_XORPS
+ x86_XRSTOR
+ x86_XRSTOR64
+ x86_XRSTORS
+ x86_XRSTORS64
+ x86_XSAVE
+ x86_XSAVE64
+ x86_XSAVEC
+ x86_XSAVEC64
+ x86_XSAVEOPT
+ x86_XSAVEOPT64
+ x86_XSAVES
+ x86_XSAVES64
+ x86_XSETBV
+ x86_XTEST
+)
+
+const x86_maxOp = x86_XTEST
+
+var x86_opNames = [...]string{
+ x86_AAA: "AAA",
+ x86_AAD: "AAD",
+ x86_AAM: "AAM",
+ x86_AAS: "AAS",
+ x86_ADC: "ADC",
+ x86_ADD: "ADD",
+ x86_ADDPD: "ADDPD",
+ x86_ADDPS: "ADDPS",
+ x86_ADDSD: "ADDSD",
+ x86_ADDSS: "ADDSS",
+ x86_ADDSUBPD: "ADDSUBPD",
+ x86_ADDSUBPS: "ADDSUBPS",
+ x86_AESDEC: "AESDEC",
+ x86_AESDECLAST: "AESDECLAST",
+ x86_AESENC: "AESENC",
+ x86_AESENCLAST: "AESENCLAST",
+ x86_AESIMC: "AESIMC",
+ x86_AESKEYGENASSIST: "AESKEYGENASSIST",
+ x86_AND: "AND",
+ x86_ANDNPD: "ANDNPD",
+ x86_ANDNPS: "ANDNPS",
+ x86_ANDPD: "ANDPD",
+ x86_ANDPS: "ANDPS",
+ x86_ARPL: "ARPL",
+ x86_BLENDPD: "BLENDPD",
+ x86_BLENDPS: "BLENDPS",
+ x86_BLENDVPD: "BLENDVPD",
+ x86_BLENDVPS: "BLENDVPS",
+ x86_BOUND: "BOUND",
+ x86_BSF: "BSF",
+ x86_BSR: "BSR",
+ x86_BSWAP: "BSWAP",
+ x86_BT: "BT",
+ x86_BTC: "BTC",
+ x86_BTR: "BTR",
+ x86_BTS: "BTS",
+ x86_CALL: "CALL",
+ x86_CBW: "CBW",
+ x86_CDQ: "CDQ",
+ x86_CDQE: "CDQE",
+ x86_CLC: "CLC",
+ x86_CLD: "CLD",
+ x86_CLFLUSH: "CLFLUSH",
+ x86_CLI: "CLI",
+ x86_CLTS: "CLTS",
+ x86_CMC: "CMC",
+ x86_CMOVA: "CMOVA",
+ x86_CMOVAE: "CMOVAE",
+ x86_CMOVB: "CMOVB",
+ x86_CMOVBE: "CMOVBE",
+ x86_CMOVE: "CMOVE",
+ x86_CMOVG: "CMOVG",
+ x86_CMOVGE: "CMOVGE",
+ x86_CMOVL: "CMOVL",
+ x86_CMOVLE: "CMOVLE",
+ x86_CMOVNE: "CMOVNE",
+ x86_CMOVNO: "CMOVNO",
+ x86_CMOVNP: "CMOVNP",
+ x86_CMOVNS: "CMOVNS",
+ x86_CMOVO: "CMOVO",
+ x86_CMOVP: "CMOVP",
+ x86_CMOVS: "CMOVS",
+ x86_CMP: "CMP",
+ x86_CMPPD: "CMPPD",
+ x86_CMPPS: "CMPPS",
+ x86_CMPSB: "CMPSB",
+ x86_CMPSD: "CMPSD",
+ x86_CMPSD_XMM: "CMPSD_XMM",
+ x86_CMPSQ: "CMPSQ",
+ x86_CMPSS: "CMPSS",
+ x86_CMPSW: "CMPSW",
+ x86_CMPXCHG: "CMPXCHG",
+ x86_CMPXCHG16B: "CMPXCHG16B",
+ x86_CMPXCHG8B: "CMPXCHG8B",
+ x86_COMISD: "COMISD",
+ x86_COMISS: "COMISS",
+ x86_CPUID: "CPUID",
+ x86_CQO: "CQO",
+ x86_CRC32: "CRC32",
+ x86_CVTDQ2PD: "CVTDQ2PD",
+ x86_CVTDQ2PS: "CVTDQ2PS",
+ x86_CVTPD2DQ: "CVTPD2DQ",
+ x86_CVTPD2PI: "CVTPD2PI",
+ x86_CVTPD2PS: "CVTPD2PS",
+ x86_CVTPI2PD: "CVTPI2PD",
+ x86_CVTPI2PS: "CVTPI2PS",
+ x86_CVTPS2DQ: "CVTPS2DQ",
+ x86_CVTPS2PD: "CVTPS2PD",
+ x86_CVTPS2PI: "CVTPS2PI",
+ x86_CVTSD2SI: "CVTSD2SI",
+ x86_CVTSD2SS: "CVTSD2SS",
+ x86_CVTSI2SD: "CVTSI2SD",
+ x86_CVTSI2SS: "CVTSI2SS",
+ x86_CVTSS2SD: "CVTSS2SD",
+ x86_CVTSS2SI: "CVTSS2SI",
+ x86_CVTTPD2DQ: "CVTTPD2DQ",
+ x86_CVTTPD2PI: "CVTTPD2PI",
+ x86_CVTTPS2DQ: "CVTTPS2DQ",
+ x86_CVTTPS2PI: "CVTTPS2PI",
+ x86_CVTTSD2SI: "CVTTSD2SI",
+ x86_CVTTSS2SI: "CVTTSS2SI",
+ x86_CWD: "CWD",
+ x86_CWDE: "CWDE",
+ x86_DAA: "DAA",
+ x86_DAS: "DAS",
+ x86_DEC: "DEC",
+ x86_DIV: "DIV",
+ x86_DIVPD: "DIVPD",
+ x86_DIVPS: "DIVPS",
+ x86_DIVSD: "DIVSD",
+ x86_DIVSS: "DIVSS",
+ x86_DPPD: "DPPD",
+ x86_DPPS: "DPPS",
+ x86_EMMS: "EMMS",
+ x86_ENTER: "ENTER",
+ x86_EXTRACTPS: "EXTRACTPS",
+ x86_F2XM1: "F2XM1",
+ x86_FABS: "FABS",
+ x86_FADD: "FADD",
+ x86_FADDP: "FADDP",
+ x86_FBLD: "FBLD",
+ x86_FBSTP: "FBSTP",
+ x86_FCHS: "FCHS",
+ x86_FCMOVB: "FCMOVB",
+ x86_FCMOVBE: "FCMOVBE",
+ x86_FCMOVE: "FCMOVE",
+ x86_FCMOVNB: "FCMOVNB",
+ x86_FCMOVNBE: "FCMOVNBE",
+ x86_FCMOVNE: "FCMOVNE",
+ x86_FCMOVNU: "FCMOVNU",
+ x86_FCMOVU: "FCMOVU",
+ x86_FCOM: "FCOM",
+ x86_FCOMI: "FCOMI",
+ x86_FCOMIP: "FCOMIP",
+ x86_FCOMP: "FCOMP",
+ x86_FCOMPP: "FCOMPP",
+ x86_FCOS: "FCOS",
+ x86_FDECSTP: "FDECSTP",
+ x86_FDIV: "FDIV",
+ x86_FDIVP: "FDIVP",
+ x86_FDIVR: "FDIVR",
+ x86_FDIVRP: "FDIVRP",
+ x86_FFREE: "FFREE",
+ x86_FFREEP: "FFREEP",
+ x86_FIADD: "FIADD",
+ x86_FICOM: "FICOM",
+ x86_FICOMP: "FICOMP",
+ x86_FIDIV: "FIDIV",
+ x86_FIDIVR: "FIDIVR",
+ x86_FILD: "FILD",
+ x86_FIMUL: "FIMUL",
+ x86_FINCSTP: "FINCSTP",
+ x86_FIST: "FIST",
+ x86_FISTP: "FISTP",
+ x86_FISTTP: "FISTTP",
+ x86_FISUB: "FISUB",
+ x86_FISUBR: "FISUBR",
+ x86_FLD: "FLD",
+ x86_FLD1: "FLD1",
+ x86_FLDCW: "FLDCW",
+ x86_FLDENV: "FLDENV",
+ x86_FLDL2E: "FLDL2E",
+ x86_FLDL2T: "FLDL2T",
+ x86_FLDLG2: "FLDLG2",
+ x86_FLDPI: "FLDPI",
+ x86_FMUL: "FMUL",
+ x86_FMULP: "FMULP",
+ x86_FNCLEX: "FNCLEX",
+ x86_FNINIT: "FNINIT",
+ x86_FNOP: "FNOP",
+ x86_FNSAVE: "FNSAVE",
+ x86_FNSTCW: "FNSTCW",
+ x86_FNSTENV: "FNSTENV",
+ x86_FNSTSW: "FNSTSW",
+ x86_FPATAN: "FPATAN",
+ x86_FPREM: "FPREM",
+ x86_FPREM1: "FPREM1",
+ x86_FPTAN: "FPTAN",
+ x86_FRNDINT: "FRNDINT",
+ x86_FRSTOR: "FRSTOR",
+ x86_FSCALE: "FSCALE",
+ x86_FSIN: "FSIN",
+ x86_FSINCOS: "FSINCOS",
+ x86_FSQRT: "FSQRT",
+ x86_FST: "FST",
+ x86_FSTP: "FSTP",
+ x86_FSUB: "FSUB",
+ x86_FSUBP: "FSUBP",
+ x86_FSUBR: "FSUBR",
+ x86_FSUBRP: "FSUBRP",
+ x86_FTST: "FTST",
+ x86_FUCOM: "FUCOM",
+ x86_FUCOMI: "FUCOMI",
+ x86_FUCOMIP: "FUCOMIP",
+ x86_FUCOMP: "FUCOMP",
+ x86_FUCOMPP: "FUCOMPP",
+ x86_FWAIT: "FWAIT",
+ x86_FXAM: "FXAM",
+ x86_FXCH: "FXCH",
+ x86_FXRSTOR: "FXRSTOR",
+ x86_FXRSTOR64: "FXRSTOR64",
+ x86_FXSAVE: "FXSAVE",
+ x86_FXSAVE64: "FXSAVE64",
+ x86_FXTRACT: "FXTRACT",
+ x86_FYL2X: "FYL2X",
+ x86_FYL2XP1: "FYL2XP1",
+ x86_HADDPD: "HADDPD",
+ x86_HADDPS: "HADDPS",
+ x86_HLT: "HLT",
+ x86_HSUBPD: "HSUBPD",
+ x86_HSUBPS: "HSUBPS",
+ x86_ICEBP: "ICEBP",
+ x86_IDIV: "IDIV",
+ x86_IMUL: "IMUL",
+ x86_IN: "IN",
+ x86_INC: "INC",
+ x86_INSB: "INSB",
+ x86_INSD: "INSD",
+ x86_INSERTPS: "INSERTPS",
+ x86_INSW: "INSW",
+ x86_INT: "INT",
+ x86_INTO: "INTO",
+ x86_INVD: "INVD",
+ x86_INVLPG: "INVLPG",
+ x86_INVPCID: "INVPCID",
+ x86_IRET: "IRET",
+ x86_IRETD: "IRETD",
+ x86_IRETQ: "IRETQ",
+ x86_JA: "JA",
+ x86_JAE: "JAE",
+ x86_JB: "JB",
+ x86_JBE: "JBE",
+ x86_JCXZ: "JCXZ",
+ x86_JE: "JE",
+ x86_JECXZ: "JECXZ",
+ x86_JG: "JG",
+ x86_JGE: "JGE",
+ x86_JL: "JL",
+ x86_JLE: "JLE",
+ x86_JMP: "JMP",
+ x86_JNE: "JNE",
+ x86_JNO: "JNO",
+ x86_JNP: "JNP",
+ x86_JNS: "JNS",
+ x86_JO: "JO",
+ x86_JP: "JP",
+ x86_JRCXZ: "JRCXZ",
+ x86_JS: "JS",
+ x86_LAHF: "LAHF",
+ x86_LAR: "LAR",
+ x86_LCALL: "LCALL",
+ x86_LDDQU: "LDDQU",
+ x86_LDMXCSR: "LDMXCSR",
+ x86_LDS: "LDS",
+ x86_LEA: "LEA",
+ x86_LEAVE: "LEAVE",
+ x86_LES: "LES",
+ x86_LFENCE: "LFENCE",
+ x86_LFS: "LFS",
+ x86_LGDT: "LGDT",
+ x86_LGS: "LGS",
+ x86_LIDT: "LIDT",
+ x86_LJMP: "LJMP",
+ x86_LLDT: "LLDT",
+ x86_LMSW: "LMSW",
+ x86_LODSB: "LODSB",
+ x86_LODSD: "LODSD",
+ x86_LODSQ: "LODSQ",
+ x86_LODSW: "LODSW",
+ x86_LOOP: "LOOP",
+ x86_LOOPE: "LOOPE",
+ x86_LOOPNE: "LOOPNE",
+ x86_LRET: "LRET",
+ x86_LSL: "LSL",
+ x86_LSS: "LSS",
+ x86_LTR: "LTR",
+ x86_LZCNT: "LZCNT",
+ x86_MASKMOVDQU: "MASKMOVDQU",
+ x86_MASKMOVQ: "MASKMOVQ",
+ x86_MAXPD: "MAXPD",
+ x86_MAXPS: "MAXPS",
+ x86_MAXSD: "MAXSD",
+ x86_MAXSS: "MAXSS",
+ x86_MFENCE: "MFENCE",
+ x86_MINPD: "MINPD",
+ x86_MINPS: "MINPS",
+ x86_MINSD: "MINSD",
+ x86_MINSS: "MINSS",
+ x86_MONITOR: "MONITOR",
+ x86_MOV: "MOV",
+ x86_MOVAPD: "MOVAPD",
+ x86_MOVAPS: "MOVAPS",
+ x86_MOVBE: "MOVBE",
+ x86_MOVD: "MOVD",
+ x86_MOVDDUP: "MOVDDUP",
+ x86_MOVDQ2Q: "MOVDQ2Q",
+ x86_MOVDQA: "MOVDQA",
+ x86_MOVDQU: "MOVDQU",
+ x86_MOVHLPS: "MOVHLPS",
+ x86_MOVHPD: "MOVHPD",
+ x86_MOVHPS: "MOVHPS",
+ x86_MOVLHPS: "MOVLHPS",
+ x86_MOVLPD: "MOVLPD",
+ x86_MOVLPS: "MOVLPS",
+ x86_MOVMSKPD: "MOVMSKPD",
+ x86_MOVMSKPS: "MOVMSKPS",
+ x86_MOVNTDQ: "MOVNTDQ",
+ x86_MOVNTDQA: "MOVNTDQA",
+ x86_MOVNTI: "MOVNTI",
+ x86_MOVNTPD: "MOVNTPD",
+ x86_MOVNTPS: "MOVNTPS",
+ x86_MOVNTQ: "MOVNTQ",
+ x86_MOVNTSD: "MOVNTSD",
+ x86_MOVNTSS: "MOVNTSS",
+ x86_MOVQ: "MOVQ",
+ x86_MOVQ2DQ: "MOVQ2DQ",
+ x86_MOVSB: "MOVSB",
+ x86_MOVSD: "MOVSD",
+ x86_MOVSD_XMM: "MOVSD_XMM",
+ x86_MOVSHDUP: "MOVSHDUP",
+ x86_MOVSLDUP: "MOVSLDUP",
+ x86_MOVSQ: "MOVSQ",
+ x86_MOVSS: "MOVSS",
+ x86_MOVSW: "MOVSW",
+ x86_MOVSX: "MOVSX",
+ x86_MOVSXD: "MOVSXD",
+ x86_MOVUPD: "MOVUPD",
+ x86_MOVUPS: "MOVUPS",
+ x86_MOVZX: "MOVZX",
+ x86_MPSADBW: "MPSADBW",
+ x86_MUL: "MUL",
+ x86_MULPD: "MULPD",
+ x86_MULPS: "MULPS",
+ x86_MULSD: "MULSD",
+ x86_MULSS: "MULSS",
+ x86_MWAIT: "MWAIT",
+ x86_NEG: "NEG",
+ x86_NOP: "NOP",
+ x86_NOT: "NOT",
+ x86_OR: "OR",
+ x86_ORPD: "ORPD",
+ x86_ORPS: "ORPS",
+ x86_OUT: "OUT",
+ x86_OUTSB: "OUTSB",
+ x86_OUTSD: "OUTSD",
+ x86_OUTSW: "OUTSW",
+ x86_PABSB: "PABSB",
+ x86_PABSD: "PABSD",
+ x86_PABSW: "PABSW",
+ x86_PACKSSDW: "PACKSSDW",
+ x86_PACKSSWB: "PACKSSWB",
+ x86_PACKUSDW: "PACKUSDW",
+ x86_PACKUSWB: "PACKUSWB",
+ x86_PADDB: "PADDB",
+ x86_PADDD: "PADDD",
+ x86_PADDQ: "PADDQ",
+ x86_PADDSB: "PADDSB",
+ x86_PADDSW: "PADDSW",
+ x86_PADDUSB: "PADDUSB",
+ x86_PADDUSW: "PADDUSW",
+ x86_PADDW: "PADDW",
+ x86_PALIGNR: "PALIGNR",
+ x86_PAND: "PAND",
+ x86_PANDN: "PANDN",
+ x86_PAUSE: "PAUSE",
+ x86_PAVGB: "PAVGB",
+ x86_PAVGW: "PAVGW",
+ x86_PBLENDVB: "PBLENDVB",
+ x86_PBLENDW: "PBLENDW",
+ x86_PCLMULQDQ: "PCLMULQDQ",
+ x86_PCMPEQB: "PCMPEQB",
+ x86_PCMPEQD: "PCMPEQD",
+ x86_PCMPEQQ: "PCMPEQQ",
+ x86_PCMPEQW: "PCMPEQW",
+ x86_PCMPESTRI: "PCMPESTRI",
+ x86_PCMPESTRM: "PCMPESTRM",
+ x86_PCMPGTB: "PCMPGTB",
+ x86_PCMPGTD: "PCMPGTD",
+ x86_PCMPGTQ: "PCMPGTQ",
+ x86_PCMPGTW: "PCMPGTW",
+ x86_PCMPISTRI: "PCMPISTRI",
+ x86_PCMPISTRM: "PCMPISTRM",
+ x86_PEXTRB: "PEXTRB",
+ x86_PEXTRD: "PEXTRD",
+ x86_PEXTRQ: "PEXTRQ",
+ x86_PEXTRW: "PEXTRW",
+ x86_PHADDD: "PHADDD",
+ x86_PHADDSW: "PHADDSW",
+ x86_PHADDW: "PHADDW",
+ x86_PHMINPOSUW: "PHMINPOSUW",
+ x86_PHSUBD: "PHSUBD",
+ x86_PHSUBSW: "PHSUBSW",
+ x86_PHSUBW: "PHSUBW",
+ x86_PINSRB: "PINSRB",
+ x86_PINSRD: "PINSRD",
+ x86_PINSRQ: "PINSRQ",
+ x86_PINSRW: "PINSRW",
+ x86_PMADDUBSW: "PMADDUBSW",
+ x86_PMADDWD: "PMADDWD",
+ x86_PMAXSB: "PMAXSB",
+ x86_PMAXSD: "PMAXSD",
+ x86_PMAXSW: "PMAXSW",
+ x86_PMAXUB: "PMAXUB",
+ x86_PMAXUD: "PMAXUD",
+ x86_PMAXUW: "PMAXUW",
+ x86_PMINSB: "PMINSB",
+ x86_PMINSD: "PMINSD",
+ x86_PMINSW: "PMINSW",
+ x86_PMINUB: "PMINUB",
+ x86_PMINUD: "PMINUD",
+ x86_PMINUW: "PMINUW",
+ x86_PMOVMSKB: "PMOVMSKB",
+ x86_PMOVSXBD: "PMOVSXBD",
+ x86_PMOVSXBQ: "PMOVSXBQ",
+ x86_PMOVSXBW: "PMOVSXBW",
+ x86_PMOVSXDQ: "PMOVSXDQ",
+ x86_PMOVSXWD: "PMOVSXWD",
+ x86_PMOVSXWQ: "PMOVSXWQ",
+ x86_PMOVZXBD: "PMOVZXBD",
+ x86_PMOVZXBQ: "PMOVZXBQ",
+ x86_PMOVZXBW: "PMOVZXBW",
+ x86_PMOVZXDQ: "PMOVZXDQ",
+ x86_PMOVZXWD: "PMOVZXWD",
+ x86_PMOVZXWQ: "PMOVZXWQ",
+ x86_PMULDQ: "PMULDQ",
+ x86_PMULHRSW: "PMULHRSW",
+ x86_PMULHUW: "PMULHUW",
+ x86_PMULHW: "PMULHW",
+ x86_PMULLD: "PMULLD",
+ x86_PMULLW: "PMULLW",
+ x86_PMULUDQ: "PMULUDQ",
+ x86_POP: "POP",
+ x86_POPA: "POPA",
+ x86_POPAD: "POPAD",
+ x86_POPCNT: "POPCNT",
+ x86_POPF: "POPF",
+ x86_POPFD: "POPFD",
+ x86_POPFQ: "POPFQ",
+ x86_POR: "POR",
+ x86_PREFETCHNTA: "PREFETCHNTA",
+ x86_PREFETCHT0: "PREFETCHT0",
+ x86_PREFETCHT1: "PREFETCHT1",
+ x86_PREFETCHT2: "PREFETCHT2",
+ x86_PREFETCHW: "PREFETCHW",
+ x86_PSADBW: "PSADBW",
+ x86_PSHUFB: "PSHUFB",
+ x86_PSHUFD: "PSHUFD",
+ x86_PSHUFHW: "PSHUFHW",
+ x86_PSHUFLW: "PSHUFLW",
+ x86_PSHUFW: "PSHUFW",
+ x86_PSIGNB: "PSIGNB",
+ x86_PSIGND: "PSIGND",
+ x86_PSIGNW: "PSIGNW",
+ x86_PSLLD: "PSLLD",
+ x86_PSLLDQ: "PSLLDQ",
+ x86_PSLLQ: "PSLLQ",
+ x86_PSLLW: "PSLLW",
+ x86_PSRAD: "PSRAD",
+ x86_PSRAW: "PSRAW",
+ x86_PSRLD: "PSRLD",
+ x86_PSRLDQ: "PSRLDQ",
+ x86_PSRLQ: "PSRLQ",
+ x86_PSRLW: "PSRLW",
+ x86_PSUBB: "PSUBB",
+ x86_PSUBD: "PSUBD",
+ x86_PSUBQ: "PSUBQ",
+ x86_PSUBSB: "PSUBSB",
+ x86_PSUBSW: "PSUBSW",
+ x86_PSUBUSB: "PSUBUSB",
+ x86_PSUBUSW: "PSUBUSW",
+ x86_PSUBW: "PSUBW",
+ x86_PTEST: "PTEST",
+ x86_PUNPCKHBW: "PUNPCKHBW",
+ x86_PUNPCKHDQ: "PUNPCKHDQ",
+ x86_PUNPCKHQDQ: "PUNPCKHQDQ",
+ x86_PUNPCKHWD: "PUNPCKHWD",
+ x86_PUNPCKLBW: "PUNPCKLBW",
+ x86_PUNPCKLDQ: "PUNPCKLDQ",
+ x86_PUNPCKLQDQ: "PUNPCKLQDQ",
+ x86_PUNPCKLWD: "PUNPCKLWD",
+ x86_PUSH: "PUSH",
+ x86_PUSHA: "PUSHA",
+ x86_PUSHAD: "PUSHAD",
+ x86_PUSHF: "PUSHF",
+ x86_PUSHFD: "PUSHFD",
+ x86_PUSHFQ: "PUSHFQ",
+ x86_PXOR: "PXOR",
+ x86_RCL: "RCL",
+ x86_RCPPS: "RCPPS",
+ x86_RCPSS: "RCPSS",
+ x86_RCR: "RCR",
+ x86_RDFSBASE: "RDFSBASE",
+ x86_RDGSBASE: "RDGSBASE",
+ x86_RDMSR: "RDMSR",
+ x86_RDPMC: "RDPMC",
+ x86_RDRAND: "RDRAND",
+ x86_RDTSC: "RDTSC",
+ x86_RDTSCP: "RDTSCP",
+ x86_RET: "RET",
+ x86_ROL: "ROL",
+ x86_ROR: "ROR",
+ x86_ROUNDPD: "ROUNDPD",
+ x86_ROUNDPS: "ROUNDPS",
+ x86_ROUNDSD: "ROUNDSD",
+ x86_ROUNDSS: "ROUNDSS",
+ x86_RSM: "RSM",
+ x86_RSQRTPS: "RSQRTPS",
+ x86_RSQRTSS: "RSQRTSS",
+ x86_SAHF: "SAHF",
+ x86_SAR: "SAR",
+ x86_SBB: "SBB",
+ x86_SCASB: "SCASB",
+ x86_SCASD: "SCASD",
+ x86_SCASQ: "SCASQ",
+ x86_SCASW: "SCASW",
+ x86_SETA: "SETA",
+ x86_SETAE: "SETAE",
+ x86_SETB: "SETB",
+ x86_SETBE: "SETBE",
+ x86_SETE: "SETE",
+ x86_SETG: "SETG",
+ x86_SETGE: "SETGE",
+ x86_SETL: "SETL",
+ x86_SETLE: "SETLE",
+ x86_SETNE: "SETNE",
+ x86_SETNO: "SETNO",
+ x86_SETNP: "SETNP",
+ x86_SETNS: "SETNS",
+ x86_SETO: "SETO",
+ x86_SETP: "SETP",
+ x86_SETS: "SETS",
+ x86_SFENCE: "SFENCE",
+ x86_SGDT: "SGDT",
+ x86_SHL: "SHL",
+ x86_SHLD: "SHLD",
+ x86_SHR: "SHR",
+ x86_SHRD: "SHRD",
+ x86_SHUFPD: "SHUFPD",
+ x86_SHUFPS: "SHUFPS",
+ x86_SIDT: "SIDT",
+ x86_SLDT: "SLDT",
+ x86_SMSW: "SMSW",
+ x86_SQRTPD: "SQRTPD",
+ x86_SQRTPS: "SQRTPS",
+ x86_SQRTSD: "SQRTSD",
+ x86_SQRTSS: "SQRTSS",
+ x86_STC: "STC",
+ x86_STD: "STD",
+ x86_STI: "STI",
+ x86_STMXCSR: "STMXCSR",
+ x86_STOSB: "STOSB",
+ x86_STOSD: "STOSD",
+ x86_STOSQ: "STOSQ",
+ x86_STOSW: "STOSW",
+ x86_STR: "STR",
+ x86_SUB: "SUB",
+ x86_SUBPD: "SUBPD",
+ x86_SUBPS: "SUBPS",
+ x86_SUBSD: "SUBSD",
+ x86_SUBSS: "SUBSS",
+ x86_SWAPGS: "SWAPGS",
+ x86_SYSCALL: "SYSCALL",
+ x86_SYSENTER: "SYSENTER",
+ x86_SYSEXIT: "SYSEXIT",
+ x86_SYSRET: "SYSRET",
+ x86_TEST: "TEST",
+ x86_TZCNT: "TZCNT",
+ x86_UCOMISD: "UCOMISD",
+ x86_UCOMISS: "UCOMISS",
+ x86_UD1: "UD1",
+ x86_UD2: "UD2",
+ x86_UNPCKHPD: "UNPCKHPD",
+ x86_UNPCKHPS: "UNPCKHPS",
+ x86_UNPCKLPD: "UNPCKLPD",
+ x86_UNPCKLPS: "UNPCKLPS",
+ x86_VERR: "VERR",
+ x86_VERW: "VERW",
+ x86_WBINVD: "WBINVD",
+ x86_WRFSBASE: "WRFSBASE",
+ x86_WRGSBASE: "WRGSBASE",
+ x86_WRMSR: "WRMSR",
+ x86_XABORT: "XABORT",
+ x86_XADD: "XADD",
+ x86_XBEGIN: "XBEGIN",
+ x86_XCHG: "XCHG",
+ x86_XEND: "XEND",
+ x86_XGETBV: "XGETBV",
+ x86_XLATB: "XLATB",
+ x86_XOR: "XOR",
+ x86_XORPD: "XORPD",
+ x86_XORPS: "XORPS",
+ x86_XRSTOR: "XRSTOR",
+ x86_XRSTOR64: "XRSTOR64",
+ x86_XRSTORS: "XRSTORS",
+ x86_XRSTORS64: "XRSTORS64",
+ x86_XSAVE: "XSAVE",
+ x86_XSAVE64: "XSAVE64",
+ x86_XSAVEC: "XSAVEC",
+ x86_XSAVEC64: "XSAVEC64",
+ x86_XSAVEOPT: "XSAVEOPT",
+ x86_XSAVEOPT64: "XSAVEOPT64",
+ x86_XSAVES: "XSAVES",
+ x86_XSAVES64: "XSAVES64",
+ x86_XSETBV: "XSETBV",
+ x86_XTEST: "XTEST",
+}
diff --git a/src/cmd/pack/Makefile b/src/cmd/pack/Makefile
deleted file mode 100644
index 3f528d751..000000000
--- a/src/cmd/pack/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include ../../Make.dist
diff --git a/src/cmd/pack/ar.c b/src/cmd/pack/ar.c
deleted file mode 100644
index 5b300dbb9..000000000
--- a/src/cmd/pack/ar.c
+++ /dev/null
@@ -1,1727 +0,0 @@
-// Inferno utils/iar/ar.c
-// http://code.google.com/p/inferno-os/source/browse/utils/iar/ar.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.
-
-/*
- * ar - portable (ascii) format version
- */
-
-/* protect a couple of our names */
-#define select your_select
-#define rcmd your_rcmd
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mach.h>
-#include "../../libmach/obj.h"
-#include <ar.h>
-
-#undef select
-#undef rcmd
-
-/*
- * The algorithm uses up to 3 temp files. The "pivot member" is the
- * archive member specified by and a, b, or i option. The temp files are
- * astart - contains existing members up to and including the pivot member.
- * amiddle - contains new files moved or inserted behind the pivot.
- * aend - contains the existing members that follow the pivot member.
- * When all members have been processed, function 'install' streams the
- * temp files, in order, back into the archive.
- */
-
-typedef struct Arsymref
-{
- char *name;
- char *file;
- int type;
- int len;
- vlong offset;
- struct Arsymref *next;
-} Arsymref;
-
-typedef struct Armember /* Temp file entry - one per archive member */
-{
- struct Armember *next;
- struct ar_hdr hdr;
- long size;
- long date;
- void *member;
-} Armember;
-
-typedef struct Arfile /* Temp file control block - one per tempfile */
-{
- char *fname; /* paging file name */
- vlong size;
- Armember *head; /* head of member chain */
- Armember *tail; /* tail of member chain */
- Arsymref *sym; /* head of defined symbol chain */
-} Arfile;
-
-typedef struct Hashchain
-{
- char *name;
- char *file;
- struct Hashchain *next;
-} Hashchain;
-
-#define NHASH 1024
-
-/*
- * macro to portably read/write archive header.
- * 'cmd' is read/write/Bread/Bwrite, etc.
- */
-#define HEADER_IO(cmd, f, h) cmd(f, h.name, sizeof(h.name)) != sizeof(h.name)\
- || cmd(f, h.date, sizeof(h.date)) != sizeof(h.date)\
- || cmd(f, h.uid, sizeof(h.uid)) != sizeof(h.uid)\
- || cmd(f, h.gid, sizeof(h.gid)) != sizeof(h.gid)\
- || cmd(f, h.mode, sizeof(h.mode)) != sizeof(h.mode)\
- || cmd(f, h.size, sizeof(h.size)) != sizeof(h.size)\
- || cmd(f, h.fmag, sizeof(h.fmag)) != sizeof(h.fmag)
-
- /* constants and flags */
-char *man = "mrxtdpq";
-char *opt = "uvnbailogS";
-char artemp[] = "/tmp/vXXXXX";
-char movtemp[] = "/tmp/v1XXXXX";
-char tailtemp[] = "/tmp/v2XXXXX";
-char symdef[] = "__.GOSYMDEF";
-char pkgdef[] = "__.PKGDEF";
-
-int aflag; /* command line flags */
-int bflag;
-int cflag;
-int gflag;
-int oflag;
-int uflag;
-int vflag;
-int Pflag; /* remove leading file prefix */
-int Sflag; /* force mark Go package as safe */
-
-int errors;
-
-Arfile *astart, *amiddle, *aend; /* Temp file control block pointers */
-int allobj = 1; /* set when all members are object files of the same type */
-int symdefsize; /* size of symdef file */
-char *pkgstmt; /* string "package foo" */
-char *objhdr; /* string "go object darwin 386 release.2010-01-01 2345+" */
-int dupfound; /* flag for duplicate symbol */
-Hashchain *hash[NHASH]; /* hash table of text symbols */
-
-#define ARNAMESIZE sizeof(astart->tail->hdr.name)
-
-char poname[ARNAMESIZE+1]; /* name of pivot member */
-char *file; /* current file or member being worked on */
-Biobuf bout;
-Biobuf bar;
-char *prefix;
-int pkgdefsafe; /* was __.PKGDEF marked safe? */
-
-void arcopy(Biobuf*, Arfile*, Armember*);
-int arcreate(char*);
-void arfree(Arfile*);
-void arinsert(Arfile*, Armember*);
-void *armalloc(int);
-char *arstrdup(char*);
-void armove(Biobuf*, Arfile*, Armember*);
-void arread(Biobuf*, Armember*);
-void arstream(int, Arfile*);
-int arwrite(int, Armember*);
-int bamatch(char*, char*);
-int duplicate(char*, char**);
-Armember *getdir(Biobuf*);
-void getpkgdef(char**, int*);
-void install(char*, Arfile*, Arfile*, Arfile*, int);
-void loadpkgdata(char*, int);
-void longt(Armember*);
-int match(int, char**);
-void mesg(int, char*);
-Arfile *newtempfile(char*);
-Armember *newmember(void);
-void objsym(Sym*, void*);
-int openar(char*, int, int);
-void pmode(long);
-void rl(int);
-void scanobj(Biobuf*, Arfile*, long);
-void scanpkg(Biobuf*, long);
-void select(int*, long);
-void setcom(void(*)(char*, int, char**));
-void skip(Biobuf*, vlong);
-void checksafe(Biobuf*, vlong);
-int symcomp(void*, void*);
-void trim(char*, char*, int);
-void usage(void);
-void wrerr(void);
-void wrsym(Biobuf*, long, Arsymref*);
-int arread_cutprefix(Biobuf*, Armember*);
-
-void rcmd(char*, int, char**); /* command processing */
-void dcmd(char*, int, char**);
-void xcmd(char*, int, char**);
-void tcmd(char*, int, char**);
-void pcmd(char*, int, char**);
-void mcmd(char*, int, char**);
-void qcmd(char*, int, char**);
-void (*comfun)(char*, int, char**);
-
-void
-main(int argc, char *argv[])
-{
- char *cp;
-
- Binit(&bout, 1, OWRITE);
- if(argc < 3)
- usage();
- for (cp = argv[1]; *cp; cp++) {
- switch(*cp) {
- case 'a': aflag = 1; break;
- case 'b': bflag = 1; break;
- case 'c': cflag = 1; break;
- case 'd': setcom(dcmd); break;
- case 'g': gflag = 1; break;
- case 'i': bflag = 1; break;
- case 'l':
- strcpy(artemp, "vXXXXX");
- strcpy(movtemp, "v1XXXXX");
- strcpy(tailtemp, "v2XXXXX");
- break;
- case 'm': setcom(mcmd); break;
- case 'o': oflag = 1; break;
- case 'p': setcom(pcmd); break;
- case 'q': setcom(qcmd); break;
- case 'r': setcom(rcmd); break;
- case 't': setcom(tcmd); break;
- case 'u': uflag = 1; break;
- case 'v': vflag = 1; break;
- case 'x': setcom(xcmd); break;
- case 'S': Sflag = 1; break;
- case 'P': Pflag = 1; break;
- default:
- fprint(2, "pack: bad option `%c'\n", *cp);
- exits("error");
- }
- }
- if (aflag && bflag) {
- fprint(2, "pack: only one of 'a' and 'b' can be specified\n");
- usage();
- }
- if(aflag || bflag) {
- trim(argv[2], poname, sizeof(poname));
- argv++;
- argc--;
- if(argc < 3)
- usage();
- }
- if(Pflag) {
- if(argc < 4) {
- fprint(2, "pack: P flag requires prefix argument\n");
- usage();
- }
- prefix = argv[2];
- argv++;
- argc--;
- }
- if(comfun == 0) {
- if(uflag == 0) {
- fprint(2, "pack: one of [%s] must be specified\n", man);
- usage();
- }
- setcom(rcmd);
- }
- cp = argv[2];
- argc -= 3;
- argv += 3;
- (*comfun)(cp, argc, argv); /* do the command */
- if(errors && cflag)
- remove(cp);
- cp = 0;
- while (argc--) {
- if (*argv) {
- fprint(2, "pack: %s not found\n", *argv);
- cp = "error";
- }
- argv++;
- }
- if (errors)
- cp = "error";
- exits(cp);
-}
-/*
- * select a command
- */
-void
-setcom(void (*fun)(char *, int, char**))
-{
-
- if(comfun != 0) {
- fprint(2, "pack: only one of [%s] allowed\n", man);
- usage();
- }
- comfun = fun;
-}
-/*
- * perform the 'r' and 'u' commands
- */
-void
-rcmd(char *arname, int count, char **files)
-{
- int fd;
- int i;
- Arfile *ap;
- Armember *bp;
- Dir *d;
- Biobuf *bfile;
-
- fd = openar(arname, ORDWR, 1);
- if (fd >= 0) {
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- }
- astart = newtempfile(artemp);
- ap = astart;
- aend = 0;
- for(i = 0; fd >= 0; i++) {
- bp = getdir(&bar);
- if (!bp)
- break;
- if (bamatch(file, poname)) { /* check for pivot */
- aend = newtempfile(tailtemp);
- ap = aend;
- }
- /* pitch symdef file */
- if (i == 0 && strcmp(file, symdef) == 0) {
- skip(&bar, bp->size);
- continue;
- }
- /* pitch pkgdef file but remember whether it was marked safe */
- if (gflag && strcmp(file, pkgdef) == 0) {
- checksafe(&bar, bp->size);
- continue;
- }
- /*
- * the plan 9 ar treats count == 0 as equivalent
- * to listing all the archive's files on the command line:
- * it will try to open every file name in the archive
- * and copy that file into the archive if it exists.
- * for go we disable that behavior, because we use
- * r with no files to make changes to the archive itself,
- * using the S or P flags.
- */
- if (!match(count, files)) {
- scanobj(&bar, ap, bp->size);
- arcopy(&bar, ap, bp);
- continue;
- }
- bfile = Bopen(file, OREAD);
- if (!bfile) {
- if (count != 0) {
- fprint(2, "pack: cannot open %s\n", file);
- errors++;
- }
- scanobj(&bar, ap, bp->size);
- arcopy(&bar, ap, bp);
- continue;
- }
- d = dirfstat(Bfildes(bfile));
- if(d == nil)
- fprint(2, "pack: cannot stat %s: %r\n", file);
- if (uflag && (d==nil || d->mtime <= bp->date)) {
- scanobj(&bar, ap, bp->size);
- arcopy(&bar, ap, bp);
- Bterm(bfile);
- free(d);
- continue;
- }
- mesg('r', file);
- skip(&bar, bp->size);
- scanobj(bfile, ap, d->length);
- free(d);
- armove(bfile, ap, bp);
- Bterm(bfile);
- }
- if(fd >= 0)
- close(fd);
- /* copy in remaining files named on command line */
- for (i = 0; i < count; i++) {
- file = files[i];
- if(file == 0)
- continue;
- files[i] = 0;
- bfile = Bopen(file, OREAD);
- if (!bfile) {
- fprint(2, "pack: cannot open %s\n", file);
- errors++;
- } else {
- mesg('a', file);
- d = dirfstat(Bfildes(bfile));
- if (d == nil)
- fprint(2, "can't stat %s\n", file);
- else {
- scanobj(bfile, astart, d->length);
- armove(bfile, astart, newmember());
- free(d);
- }
- Bterm(bfile);
- }
- }
- if(fd < 0 && !cflag)
- install(arname, astart, 0, aend, 1); /* issue 'creating' msg */
- else
- install(arname, astart, 0, aend, 0);
-}
-
-void
-dcmd(char *arname, int count, char **files)
-{
- Armember *bp;
- int fd, i;
-
- if (!count)
- return;
- fd = openar(arname, ORDWR, 0);
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- astart = newtempfile(artemp);
- for (i = 0; bp = getdir(&bar); i++) {
- if(match(count, files)) {
- mesg('d', file);
- skip(&bar, bp->size);
- if (strcmp(file, symdef) == 0)
- allobj = 0;
- } else if (i == 0 && strcmp(file, symdef) == 0) {
- skip(&bar, bp->size);
- } else if (gflag && strcmp(file, pkgdef) == 0) {
- skip(&bar, bp->size);
- } else {
- scanobj(&bar, astart, bp->size);
- arcopy(&bar, astart, bp);
- }
- }
- close(fd);
- install(arname, astart, 0, 0, 0);
-}
-
-void
-xcmd(char *arname, int count, char **files)
-{
- int fd, f, mode, i;
- Armember *bp;
- Dir dx;
-
- fd = openar(arname, OREAD, 0);
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- i = 0;
- while (bp = getdir(&bar)) {
- if(count == 0 || match(count, files)) {
- mode = strtoul(bp->hdr.mode, 0, 8) & 0777;
- f = create(file, OWRITE, mode);
- if(f < 0) {
- fprint(2, "pack: %s cannot create\n", file);
- skip(&bar, bp->size);
- } else {
- mesg('x', file);
- arcopy(&bar, 0, bp);
- if (write(f, bp->member, bp->size) < 0)
- wrerr();
- if(oflag && bp->date != 0) {
- nulldir(&dx);
- dx.atime = bp->date;
- dx.mtime = bp->date;
- if(dirwstat(file, &dx) < 0)
- perror(file);
- }
- free(bp->member);
- close(f);
- }
- free(bp);
- if (count && ++i >= count)
- break;
- } else {
- skip(&bar, bp->size);
- free(bp);
- }
- }
- close(fd);
-}
-void
-pcmd(char *arname, int count, char **files)
-{
- int fd;
- Armember *bp;
-
- fd = openar(arname, OREAD, 0);
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- while(bp = getdir(&bar)) {
- if(count == 0 || match(count, files)) {
- if(vflag)
- print("\n<%s>\n\n", file);
- arcopy(&bar, 0, bp);
- if (write(1, bp->member, bp->size) < 0)
- wrerr();
- } else
- skip(&bar, bp->size);
- free(bp);
- }
- close(fd);
-}
-void
-mcmd(char *arname, int count, char **files)
-{
- int fd, i;
- Arfile *ap;
- Armember *bp;
-
- if (count == 0)
- return;
- fd = openar(arname, ORDWR, 0);
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- astart = newtempfile(artemp);
- amiddle = newtempfile(movtemp);
- aend = 0;
- ap = astart;
- for (i = 0; bp = getdir(&bar); i++) {
- if (bamatch(file, poname)) {
- aend = newtempfile(tailtemp);
- ap = aend;
- }
- if(match(count, files)) {
- mesg('m', file);
- scanobj(&bar, amiddle, bp->size);
- arcopy(&bar, amiddle, bp);
- } else if (ap == astart && i == 0 && strcmp(file, symdef) == 0) {
- /*
- * pitch the symdef file if it is at the beginning
- * of the archive and we aren't inserting in front
- * of it (ap == astart).
- */
- skip(&bar, bp->size);
- } else if (ap == astart && gflag && strcmp(file, pkgdef) == 0) {
- /*
- * pitch the pkgdef file if we aren't inserting in front
- * of it (ap == astart).
- */
- skip(&bar, bp->size);
- } else {
- scanobj(&bar, ap, bp->size);
- arcopy(&bar, ap, bp);
- }
- }
- close(fd);
- if (poname[0] && aend == 0)
- fprint(2, "pack: %s not found - files moved to end.\n", poname);
- install(arname, astart, amiddle, aend, 0);
-}
-void
-tcmd(char *arname, int count, char **files)
-{
- int fd;
- Armember *bp;
- char name[ARNAMESIZE+1];
-
- fd = openar(arname, OREAD, 0);
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- while(bp = getdir(&bar)) {
- if(count == 0 || match(count, files)) {
- if(vflag)
- longt(bp);
- trim(file, name, ARNAMESIZE);
- Bprint(&bout, "%s\n", name);
- }
- skip(&bar, bp->size);
- free(bp);
- }
- close(fd);
-}
-void
-qcmd(char *arname, int count, char **files)
-{
- int fd, i;
- Armember *bp;
- Biobuf *bfile;
-
- if(aflag || bflag) {
- fprint(2, "pack: abi not allowed with q\n");
- exits("error");
- }
- fd = openar(arname, ORDWR, 1);
- if (fd < 0) {
- if(!cflag)
- fprint(2, "pack: creating %s\n", arname);
- fd = arcreate(arname);
- }
- Binit(&bar, fd, OREAD);
- Bseek(&bar,seek(fd,0,1), 1);
- /* leave note group behind when writing archive; i.e. sidestep interrupts */
- rfork(RFNOTEG);
- Bseek(&bar, 0, 2);
- bp = newmember();
- for(i=0; i<count && files[i]; i++) {
- file = files[i];
- files[i] = 0;
- bfile = Bopen(file, OREAD);
- if(!bfile) {
- fprint(2, "pack: cannot open %s\n", file);
- errors++;
- } else {
- mesg('q', file);
- armove(bfile, 0, bp);
- if (!arwrite(fd, bp))
- wrerr();
- free(bp->member);
- bp->member = 0;
- Bterm(bfile);
- }
- }
- free(bp);
- close(fd);
-}
-
-/*
- * does the object header line p match the last one we saw?
- * update *lastp if it gets more specific.
- */
-int
-matchhdr(char *p, char **lastp)
-{
- int n;
- char *last;
-
- // no information?
- last = *lastp;
- if(last == nil) {
- *lastp = strdup(p);
- return 1;
- }
-
- // identical match?
- if(strcmp(last, p) == 0)
- return 1;
-
- // last has extra fields
- n = strlen(p);
- if(n < strlen(last) && last[n] == ' ')
- return 1;
-
- // p has extra fields - save in last
- n = strlen(last);
- if(n < strlen(p) && p[n] == ' ') {
- free(last);
- *lastp = strdup(p);
- return 1;
- }
-
- return 0;
-}
-
-/*
- * extract the symbol references from an object file
- */
-void
-scanobj(Biobuf *b, Arfile *ap, long size)
-{
- int obj, goobject;
- vlong offset, offset1;
- Dir *d;
- static int lastobj = -1;
- uchar buf[4];
- char *p;
-
- if (!allobj) /* non-object file encountered */
- return;
- offset = Boffset(b);
- obj = objtype(b, 0);
- if (obj < 0) { /* not an object file */
- /* maybe a foreign object file */
- Bseek(b, offset, 0);
- memset(buf, 0, sizeof buf);
- Bread(b, buf, 4);
-
- /* maybe a foreign object file? that's okay */
- if((buf[0] == 0x7F && buf[1] == 'E' && buf[2] == 'L' && buf[3] == 'F') || // ELF
- (buf[0] == 0x4c && buf[1] == 0x01 || buf[0] == 0x64 && buf[1] == 0x86) || // Windows PE
- (buf[0] == 0xFE && buf[1] == 0xED && buf[2] == 0xFA && (buf[3]&~1) == 0xCE) || // Mach-O big-endian
- (buf[3] == 0xFE && buf[2] == 0xED && buf[1] == 0xFA && (buf[0]&~1) == 0xCE)) { // Mach-O little-endian
- Bseek(b, offset, 0);
- return;
- }
-
- if (!gflag || strcmp(file, pkgdef) != 0) { /* don't clear allobj if it's pkg defs */
- fprint(2, "pack: non-object file %s\n", file);
- errors++;
- allobj = 0;
- }
- d = dirfstat(Bfildes(b));
- if (d != nil && d->length == 0) {
- fprint(2, "pack: zero length file %s\n", file);
- errors++;
- }
- free(d);
- Bseek(b, offset, 0);
- return;
- }
-
- goobject = 1;
- offset1 = Boffset(b);
- Bseek(b, offset, 0);
- p = Brdstr(b, '\n', 1);
-
- // After the go object header comes the Go metadata,
- // followed by ! on a line by itself. If this is not a Go object,
- // the ! comes immediately. Catch that so we can avoid
- // the call to scanpkg below, since scanpkg assumes that the
- // Go metadata is present.
- if(BGETC(b) == '!')
- goobject = 0;
-
- Bseek(b, offset1, 0);
- if(p == nil || strncmp(p, "go object ", 10) != 0) {
- fprint(2, "pack: malformed object file %s\n", file);
- errors++;
- Bseek(b, offset, 0);
- free(p);
- return;
- }
-
- if (!matchhdr(p, &objhdr)) {
- fprint(2, "pack: inconsistent object file %s: [%s] vs [%s]\n", file, p, objhdr);
- errors++;
- allobj = 0;
- free(p);
- return;
- }
- free(p);
-
- // Old check. Should be impossible since objhdrs match, but keep the check anyway.
- if (lastobj >= 0 && obj != lastobj) {
- fprint(2, "pack: inconsistent object file %s\n", file);
- errors++;
- allobj = 0;
- return;
- }
- lastobj = obj;
-
- if (!readar(b, obj, offset+size, 0)) {
- fprint(2, "pack: invalid symbol reference in file %s\n", file);
- errors++;
- allobj = 0;
- Bseek(b, offset, 0);
- return;
- }
- Bseek(b, offset, 0);
- objtraverse(objsym, ap);
- if (gflag && goobject) {
- scanpkg(b, size);
- Bseek(b, offset, 0);
- }
-}
-
-/*
- * does line contain substring (length-limited)
- */
-int
-strstrn(char *line, int len, char *sub)
-{
- int i;
- int sublen;
-
- sublen = strlen(sub);
- for (i = 0; i < len - sublen; i++)
- if (memcmp(line+i, sub, sublen) == 0)
- return 1;
- return 0;
-}
-
-/*
- * package import data
- */
-int safe = 1;
-char* pkgname;
-char* importblock;
-
-void
-getpkgdef(char **datap, int *lenp)
-{
- char *tag, *hdr;
-
- if(pkgname == nil) {
- pkgname = "__emptyarchive__";
- importblock = "";
- }
-
- tag = "";
- if(safe || Sflag)
- tag = "safe";
-
- hdr = "empty archive";
- if(objhdr != nil)
- hdr = objhdr;
-
- *datap = smprint("%s\nimport\n$$\npackage %s %s\n%s\n$$\n", hdr, pkgname, tag, importblock);
- *lenp = strlen(*datap);
-}
-
-/*
- * extract the package definition data from an object file.
- * there can be only one.
- */
-void
-scanpkg(Biobuf *b, long size)
-{
- long n;
- int c;
- long start, end, pkgsize;
- char *data, *line, pkgbuf[1024], *pkg;
- int first;
-
- /*
- * scan until $$
- */
- for (n=0; n<size; ) {
- c = BGETC(b);
- if(c == Beof)
- break;
- n++;
- if(c != '$')
- continue;
- c = BGETC(b);
- if(c == Beof)
- break;
- n++;
- if(c != '$')
- continue;
- goto foundstart;
- }
- // fprint(2, "pack: warning: no package import section in %s\n", file);
- if(b != &bar || !pkgdefsafe)
- safe = 0; // non-Go file (C or assembly)
- return;
-
-foundstart:
- /* found $$; skip rest of line */
- while((c = BGETC(b)) != '\n')
- if(c == Beof)
- goto bad;
-
- /* how big is it? */
- first = 1;
- start = end = 0;
- for (n=0; n<size; n+=Blinelen(b)) {
- line = Brdstr(b, '\n', 0);
- if (line == nil)
- goto bad;
- if (first && strstrn(line, Blinelen(b), "package ")) {
- if (Blinelen(b) > sizeof(pkgbuf)-1)
- goto bad;
- memmove(pkgbuf, line, Blinelen(b));
- pkgbuf[Blinelen(b)] = '\0';
- pkg = pkgbuf;
- while(*pkg == ' ' || *pkg == '\t')
- pkg++;
- if(strncmp(pkg, "package ", 8) != 0)
- goto bad;
- pkg += 8;
- data = pkg;
- while(*pkg != ' ' && *pkg != '\n' && *pkg != '\0')
- pkg++;
- pkgname = armalloc(pkg - data + 1);
- memmove(pkgname, data, pkg - data);
- pkgname[pkg-data] = '\0';
- if(strcmp(pkg, " safe\n") != 0 && (b != &bar || !pkgdefsafe))
- safe = 0;
- start = Boffset(b); // after package statement
- first = 0;
- free(line);
- continue;
- }
- if(line[0] == '$' && line[1] == '$') {
- free(line);
- goto foundend;
- }
- end = Boffset(b); // before closing $$
- free(line);
- }
-bad:
- fprint(2, "pack: bad package import section in %s\n", file);
- errors++;
- return;
-
-foundend:
- if (start == 0)
- return;
- if (end == 0)
- goto bad;
- if(importblock != nil) {
- fprint(2, "pack: multiple Go object files\n");
- errors++;
- return;
- }
- pkgsize = end-start;
- data = armalloc(end - start + 1);
- Bseek(b, start, 0);
- if (Bread(b, data, pkgsize) != pkgsize) {
- fprint(2, "pack: error reading package import section in %s\n", file);
- errors++;
- return;
- }
- data[end-start] = '\0';
- importblock = data;
-}
-
-/*
- * add text and data symbols to the symbol list
- */
-void
-objsym(Sym *s, void *p)
-{
- int n;
- Arsymref *as;
- Arfile *ap;
- char *ofile;
-
- if (s->type != 'T' && s->type != 'D')
- return;
- ap = (Arfile*)p;
- as = armalloc(sizeof(Arsymref));
- as->offset = ap->size;
- as->name = arstrdup(s->name);
- as->file = arstrdup(file);
- if(s->type == 'T' && duplicate(as->name, &ofile)) {
- dupfound = 1;
- fprint(2, "duplicate text symbol: %s and %s: %s\n", as->file, ofile, as->name);
- errors++;
- free(as->name);
- free(as);
- return;
- }
- as->type = s->type;
- n = strlen(s->name);
- symdefsize += 4+(n+1)+1;
- as->len = n;
- as->next = ap->sym;
- ap->sym = as;
-}
-
-/*
- * Check the symbol table for duplicate text symbols
- */
-int
-hashstr(char *name)
-{
- uint32 h;
- char *cp;
-
- h = 0;
- for(cp = name; *cp; h += *cp++)
- h *= 1119;
- return h & 0xfffffff;
-}
-
-int
-duplicate(char *name, char **ofile)
-{
- Hashchain *p;
- int h;
-
- h = hashstr(name) % NHASH;
-
- for(p = hash[h]; p; p = p->next)
- if(strcmp(p->name, name) == 0) {
- *ofile = p->file;
- return 1;
- }
- p = armalloc(sizeof(Hashchain));
- p->next = hash[h];
- p->name = name;
- p->file = file;
- hash[h] = p;
- *ofile = nil;
- return 0;
-}
-
-/*
- * open an archive and validate its header
- */
-int
-openar(char *arname, int mode, int errok)
-{
- int fd;
- char mbuf[SARMAG];
-
- fd = open(arname, mode);
- if(fd >= 0){
- if(read(fd, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) {
- fprint(2, "pack: %s not in archive format\n", arname);
- exits("error");
- }
- }else if(!errok){
- fprint(2, "pack: cannot open %s: %r\n", arname);
- exits("error");
- }
- return fd;
-}
-
-/*
- * create an archive and set its header
- */
-int
-arcreate(char *arname)
-{
- int fd;
-
- fd = create(arname, OWRITE, 0664);
- if(fd < 0){
- fprint(2, "pack: cannot create %s: %r\n", arname);
- exits("error");
- }
- if(write(fd, ARMAG, SARMAG) != SARMAG)
- wrerr();
- return fd;
-}
-
-/*
- * error handling
- */
-void
-wrerr(void)
-{
- perror("pack: write error");
- exits("error");
-}
-
-void
-rderr(void)
-{
- perror("pack: read error");
- exits("error");
-}
-
-void
-phaseerr(int offset)
-{
- fprint(2, "pack: phase error at offset %d\n", offset);
- exits("error");
-}
-
-void
-usage(void)
-{
- fprint(2, "usage: pack [%s][%s][P prefix] archive files ...\n", opt, man);
- exits("error");
-}
-
-/*
- * read the header for the next archive member
- */
-Armember *
-getdir(Biobuf *b)
-{
- Armember *bp;
- char *cp;
- static char name[ARNAMESIZE+1];
-
- bp = newmember();
- if(HEADER_IO(Bread, b, bp->hdr)) {
- free(bp);
- return 0;
- }
- if(strncmp(bp->hdr.fmag, ARFMAG, sizeof(bp->hdr.fmag)))
- phaseerr(Boffset(b));
- strncpy(name, bp->hdr.name, sizeof(bp->hdr.name));
- cp = name+sizeof(name)-1;
- while(*--cp==' ')
- ;
- cp[1] = '\0';
- file = arstrdup(name);
- bp->date = strtol(bp->hdr.date, 0, 0);
- bp->size = strtol(bp->hdr.size, 0, 0);
- return bp;
-}
-
-/*
- * Copy the file referenced by fd to the temp file
- */
-void
-armove(Biobuf *b, Arfile *ap, Armember *bp)
-{
- char *cp;
- Dir *d;
- vlong n;
-
- d = dirfstat(Bfildes(b));
- if (d == nil) {
- fprint(2, "pack: cannot stat %s\n", file);
- return;
- }
-
- trim(file, bp->hdr.name, sizeof(bp->hdr.name));
- for (cp = strchr(bp->hdr.name, 0); /* blank pad on right */
- cp < bp->hdr.name+sizeof(bp->hdr.name); cp++)
- *cp = ' ';
- sprint(bp->hdr.date, "%-12ld", 0L); // was d->mtime but removed for idempotent builds
- sprint(bp->hdr.uid, "%-6d", 0);
- sprint(bp->hdr.gid, "%-6d", 0);
- sprint(bp->hdr.mode, "%-8lo", d->mode);
- sprint(bp->hdr.size, "%-10lld", d->length);
- strncpy(bp->hdr.fmag, ARFMAG, 2);
- bp->size = d->length;
- arread(b, bp);
- n = bp->size;
- if (n&1)
- n++;
- if (ap) {
- arinsert(ap, bp);
- ap->size += n+SAR_HDR;
- }
- free(d);
-}
-
-/*
- * Copy the archive member at the current offset into the temp file.
- */
-void
-arcopy(Biobuf *b, Arfile *ap, Armember *bp)
-{
- long n;
-
- arread(b, bp);
- n = bp->size;
- if (n & 01)
- n++;
- if (ap) {
- arinsert(ap, bp);
- ap->size += n+SAR_HDR;
- }
-}
-
-/*
- * Skip an archive member
- */
-void
-skip(Biobuf *bp, vlong len)
-{
- if (len & 01)
- len++;
- Bseek(bp, len, 1);
-}
-
-void
-checksafe(Biobuf *bp, vlong len)
-{
- char *p;
- vlong end;
-
- if (len & 01)
- len++;
- end = Boffset(bp) + len;
-
- p = Brdline(bp, '\n');
- if(p == nil || strncmp(p, "go object ", 10) != 0)
- goto done;
- for(;;) {
- p = Brdline(bp, '\n');
- if(p == nil || Boffset(bp) >= end)
- goto done;
- if(strncmp(p, "$$\n", 3) == 0)
- break;
- }
- p = Brdline(bp, '\n');
- if(p == nil || Boffset(bp) > end)
- goto done;
- if(Blinelen(bp) > 8+6 && strncmp(p, "package ", 8) == 0 && strncmp(p+Blinelen(bp)-6, " safe\n", 6) == 0)
- pkgdefsafe = 1;
-
-done:
- Bseek(bp, end, 0);
-}
-
-/*
- * Stream the three temp files to an archive
- */
-void
-install(char *arname, Arfile *astart, Arfile *amiddle, Arfile *aend, int createflag)
-{
- int fd;
-
- if(allobj && dupfound) {
- fprint(2, "%s not changed\n", arname);
- return;
- }
- /* leave note group behind when copying back; i.e. sidestep interrupts */
- rfork(RFNOTEG);
-
- if(createflag)
- fprint(2, "pack: creating %s\n", arname);
- fd = arcreate(arname);
-
- if(allobj)
- rl(fd);
-
- if (astart) {
- arstream(fd, astart);
- arfree(astart);
- }
- if (amiddle) {
- arstream(fd, amiddle);
- arfree(amiddle);
- }
- if (aend) {
- arstream(fd, aend);
- arfree(aend);
- }
- close(fd);
-}
-
-void
-rl(int fd)
-{
- Biobuf b;
- char *cp;
- struct ar_hdr a;
- long len;
- int headlen;
- char *pkgdefdata;
- int pkgdefsize;
-
- pkgdefdata = nil;
- pkgdefsize = 0;
-
- Binit(&b, fd, OWRITE);
- Bseek(&b,seek(fd,0,1), 0);
-
- len = symdefsize;
- if(len&01)
- len++;
- sprint(a.date, "%-12ld", 0L); // time(0)
- sprint(a.uid, "%-6d", 0);
- sprint(a.gid, "%-6d", 0);
- sprint(a.mode, "%-8lo", 0644L);
- sprint(a.size, "%-10ld", len);
- strncpy(a.fmag, ARFMAG, 2);
- strcpy(a.name, symdef);
- for (cp = strchr(a.name, 0); /* blank pad on right */
- cp < a.name+sizeof(a.name); cp++)
- *cp = ' ';
- if(HEADER_IO(Bwrite, &b, a))
- wrerr();
-
- headlen = Boffset(&b);
- len += headlen;
- if (gflag) {
- getpkgdef(&pkgdefdata, &pkgdefsize);
- len += SAR_HDR + pkgdefsize;
- if (len & 1)
- len++;
- }
- if (astart) {
- wrsym(&b, len, astart->sym);
- len += astart->size;
- }
- if(amiddle) {
- wrsym(&b, len, amiddle->sym);
- len += amiddle->size;
- }
- if(aend)
- wrsym(&b, len, aend->sym);
-
- if(symdefsize&0x01)
- BPUTC(&b, 0);
-
- if (gflag) {
- len = pkgdefsize;
- sprint(a.date, "%-12ld", 0L); // time(0)
- sprint(a.uid, "%-6d", 0);
- sprint(a.gid, "%-6d", 0);
- sprint(a.mode, "%-8lo", 0644L);
- sprint(a.size, "%-10ld", (len + 1) & ~1);
- strncpy(a.fmag, ARFMAG, 2);
- strcpy(a.name, pkgdef);
- for (cp = strchr(a.name, 0); /* blank pad on right */
- cp < a.name+sizeof(a.name); cp++)
- *cp = ' ';
- if(HEADER_IO(Bwrite, &b, a))
- wrerr();
-
- if (Bwrite(&b, pkgdefdata, pkgdefsize) != pkgdefsize)
- wrerr();
- if(len&0x01)
- BPUTC(&b, 0);
- }
- Bterm(&b);
-}
-
-/*
- * Write the defined symbols to the symdef file
- */
-void
-wrsym(Biobuf *bp, long offset, Arsymref *as)
-{
- int off;
-
- while(as) {
- BPUTC(bp, as->type);
- off = as->offset+offset;
- BPUTLE4(bp, off);
- if (Bwrite(bp, as->name, as->len+1) != as->len+1)
- wrerr();
- as = as->next;
- }
-}
-
-/*
- * Check if the archive member matches an entry on the command line.
- */
-int
-match(int count, char **files)
-{
- int i;
- char name[ARNAMESIZE+1];
-
- for(i=0; i<count; i++) {
- if(files[i] == 0)
- continue;
- trim(files[i], name, ARNAMESIZE);
- if(strncmp(name, file, ARNAMESIZE) == 0) {
- file = files[i];
- files[i] = 0;
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * compare the current member to the name of the pivot member
- */
-int
-bamatch(char *file, char *pivot)
-{
- static int state = 0;
-
- switch(state)
- {
- case 0: /* looking for position file */
- if (aflag) {
- if (strncmp(file, pivot, ARNAMESIZE) == 0)
- state = 1;
- } else if (bflag) {
- if (strncmp(file, pivot, ARNAMESIZE) == 0) {
- state = 2; /* found */
- return 1;
- }
- }
- break;
- case 1: /* found - after previous file */
- state = 2;
- return 1;
- case 2: /* already found position file */
- break;
- }
- return 0;
-}
-
-/*
- * output a message, if 'v' option was specified
- */
-void
-mesg(int c, char *file)
-{
-
- if(vflag)
- Bprint(&bout, "%c - %s\n", c, file);
-}
-
-/*
- * isolate file name by stripping leading directories and trailing slashes
- */
-void
-trim(char *s, char *buf, int n)
-{
- char *p, *q;
-
- for(;;) {
- p = strrchr(s, '/');
- q = strrchr(s, '\\');
- if (q > p)
- p = q;
- if (!p) { /* no (back)slash in name */
- strncpy(buf, s, n);
- return;
- }
- if (p[1] != 0) { /* p+1 is first char of file name */
- strncpy(buf, p+1, n);
- return;
- }
- *p = 0; /* strip trailing (back)slash */
- }
-}
-
-/*
- * utilities for printing long form of 't' command
- */
-#define SUID 04000
-#define SGID 02000
-#define ROWN 0400
-#define WOWN 0200
-#define XOWN 0100
-#define RGRP 040
-#define WGRP 020
-#define XGRP 010
-#define ROTH 04
-#define WOTH 02
-#define XOTH 01
-#define STXT 01000
-
-void
-longt(Armember *bp)
-{
- char *cp;
-
- pmode(strtoul(bp->hdr.mode, 0, 8));
- Bprint(&bout, "%3ld/%1ld", strtol(bp->hdr.uid, 0, 0), strtol(bp->hdr.gid, 0, 0));
- Bprint(&bout, "%7ld", bp->size);
- cp = ctime(bp->date);
- Bprint(&bout, " %-12.12s %-4.4s ", cp+4, cp+24);
-}
-
-int m1[] = { 1, ROWN, 'r', '-' };
-int m2[] = { 1, WOWN, 'w', '-' };
-int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
-int m4[] = { 1, RGRP, 'r', '-' };
-int m5[] = { 1, WGRP, 'w', '-' };
-int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
-int m7[] = { 1, ROTH, 'r', '-' };
-int m8[] = { 1, WOTH, 'w', '-' };
-int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
-
-int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};
-
-void
-pmode(long mode)
-{
- int **mp;
-
- for(mp = &m[0]; mp < &m[9];)
- select(*mp++, mode);
-}
-
-void
-select(int *ap, long mode)
-{
- int n;
-
- n = *ap++;
- while(--n>=0 && (mode&*ap++)==0)
- ap++;
- BPUTC(&bout, *ap);
-}
-
-/*
- * Temp file I/O subsystem. We attempt to cache all three temp files in
- * core. When we run out of memory we spill to disk.
- * The I/O model assumes that temp files:
- * 1) are only written on the end
- * 2) are only read from the beginning
- * 3) are only read after all writing is complete.
- * The architecture uses one control block per temp file. Each control
- * block anchors a chain of buffers, each containing an archive member.
- */
-Arfile *
-newtempfile(char *name) /* allocate a file control block */
-{
- Arfile *ap;
-
- ap = armalloc(sizeof(Arfile));
- ap->fname = name;
- return ap;
-}
-
-Armember *
-newmember(void) /* allocate a member buffer */
-{
- return armalloc(sizeof(Armember));
-}
-
-void
-arread(Biobuf *b, Armember *bp) /* read an image into a member buffer */
-{
- int i;
- vlong off;
-
- bp->member = armalloc(bp->size);
-
- // If P flag is set, let arread_cutprefix try.
- // If it succeeds, we're done. If not, fall back
- // to a direct copy.
- off = Boffset(b);
- if(Pflag && arread_cutprefix(b, bp))
- return;
- Bseek(b, off, 0);
-
- i = Bread(b, bp->member, bp->size);
- if (i < 0) {
- free(bp->member);
- bp->member = 0;
- rderr();
- }
- if(bp->size&1)
- BGETC(b);
-}
-
-/*
- * insert a member buffer into the member chain
- */
-void
-arinsert(Arfile *ap, Armember *bp)
-{
- bp->next = 0;
- if (!ap->tail)
- ap->head = bp;
- else
- ap->tail->next = bp;
- ap->tail = bp;
-}
-
-/*
- * stream the members in a temp file to the file referenced by 'fd'.
- */
-void
-arstream(int fd, Arfile *ap)
-{
- Armember *bp;
-
- /* dump the in-core buffers */
- for (bp = ap->head; bp; bp = bp->next) {
- if (!arwrite(fd, bp))
- wrerr();
- }
-}
-
-/*
- * write a member to 'fd'.
- */
-int
-arwrite(int fd, Armember *bp)
-{
- int len;
-
- if(HEADER_IO(write, fd, bp->hdr))
- return 0;
- len = bp->size;
- if (len & 01)
- len++;
- if (write(fd, bp->member, len) != len)
- return 0;
- return 1;
-}
-
-void
-arfree(Arfile *ap) /* free a member buffer */
-{
- Armember *bp, *next;
-
- for (bp = ap->head; bp; bp = next) {
- next = bp->next;
- if (bp->member)
- free(bp->member);
- free(bp);
- }
- free(ap);
-}
-
-/*
- * allocate space for a control block or member buffer. if the malloc
- * fails we try to reclaim space by spilling previously allocated
- * member buffers.
- */
-void *
-armalloc(int n)
-{
- char *cp;
-
- // bump so that arwrite can do the same
- if(n&1)
- n++;
-
- cp = malloc(n);
- if (cp) {
- memset(cp, 0, n);
- return cp;
- }
- fprint(2, "pack: out of memory\n");
- exits("malloc");
- return 0;
-}
-
-char *
-arstrdup(char *s)
-{
- char *t;
-
- t = armalloc(strlen(s) + 1);
- strcpy(t, s);
- return t;
-}
-
-
-/*
- * Parts of libmach we're not supposed
- * to look at but need for arread_cutprefix.
- */
-extern int _read5(Biobuf*, Prog*);
-extern int _read6(Biobuf*, Prog*);
-extern int _read8(Biobuf*, Prog*);
-int (*reader[256])(Biobuf*, Prog*) = {
- [ObjArm] = _read5,
- [ObjAmd64] = _read6,
- [Obj386] = _read8,
-};
-
-#define isdelim(c) ((c) == '/' || (c) == '\\')
-
-/*
- * check if p is start of windows full path, like C:\ or c:/.
- * return 1 if so. also set drive parameter to its
- * upper-case drive letter.
- */
-int
-iswinpathstart(char *p, char *drive)
-{
- if('A' <= p[0] || p[0] <= 'Z')
- *drive = p[0];
- else if('a' <= p[0] || p[0] <= 'z')
- *drive = p[0] - ('a' - 'A');
- else
- return 0;
- return p[1] == ':' && isdelim(p[2]);
-}
-
-/*
- * copy b into bp->member but rewrite object
- * during copy to drop prefix from all file names.
- * return 1 if b was recognized as an object file
- * and copied successfully, 0 otherwise.
- */
-int
-arread_cutprefix(Biobuf *b, Armember *bp)
-{
- vlong offset, o, end;
- int n, t;
- int (*rd)(Biobuf*, Prog*);
- char *w, *inprefix, d1, d2;
- Prog p;
-
- offset = Boffset(b);
- end = offset + bp->size;
- t = objtype(b, nil);
- if(t < 0)
- return 0;
- if((rd = reader[t]) == nil)
- return 0;
-
- // copy header
- w = bp->member;
- n = Boffset(b) - offset;
- Bseek(b, -n, 1);
- if(Bread(b, w, n) != n)
- return 0;
- offset += n;
- w += n;
-
- // read object file one pseudo-instruction at a time,
- // eliding the file name instructions that refer to
- // the prefix.
- memset(&p, 0, sizeof p);
- inprefix = nil;
- while(Boffset(b) < end && rd(b, &p)) {
- if(p.kind == aName && p.type == UNKNOWN && p.sym == 1 && p.id[0] == '<') {
- // part of a file path.
- // we'll keep continuing (skipping the copy)
- // around the loop until either we get to a
- // name piece that should be kept or we see
- // the whole prefix.
-
- if(inprefix == nil && prefix[0] == '/' && p.id[1] == '/' && p.id[2] == '\0') {
- // leading /
- inprefix = prefix+1;
- } else if(inprefix == nil && iswinpathstart(prefix, &d1) && iswinpathstart(p.id + 1, &d2) && d1 == d2 && p.id[4] == '\0') {
- // leading c:\ ...
- inprefix = prefix+3;
- } else if(inprefix != nil) {
- // handle subsequent elements
- n = strlen(p.id+1);
- if(strncmp(p.id+1, inprefix, n) == 0 && (isdelim(inprefix[n]) || inprefix[n] == '\0')) {
- inprefix += n;
- if(isdelim(inprefix[0]))
- inprefix++;
- }
- }
-
- if(inprefix && inprefix[0] == '\0') {
- // reached end of prefix.
- // if we another path element follows,
- // nudge the offset to skip over the prefix we saw.
- // if not, leave offset alone, to emit the whole name.
- // additional name elements will not be skipped
- // because inprefix is now nil and we won't see another
- // leading / in this name.
- inprefix = nil;
- o = Boffset(b);
- if(o < end && rd(b, &p) && p.kind == aName && p.type == UNKNOWN && p.sym == 1 && p.id[0] == '<') {
- // print("skip %lld-%lld\n", offset, o);
- offset = o;
- }
- }
- } else {
- // didn't find the whole prefix.
- // give up and let it emit the entire name.
- inprefix = nil;
- }
-
- // copy instructions
- if(!inprefix) {
- n = Boffset(b) - offset;
- Bseek(b, -n, 1);
- if(Bread(b, w, n) != n)
- return 0;
- offset += n;
- w += n;
- }
- }
- bp->size = w - (char*)bp->member;
- sprint(bp->hdr.size, "%-10lld", (vlong)bp->size);
- strncpy(bp->hdr.fmag, ARFMAG, 2);
- Bseek(b, end, 0);
- if(Boffset(b)&1)
- BGETC(b);
- return 1;
-}
diff --git a/src/cmd/pack/doc.go b/src/cmd/pack/doc.go
index 67b789731..1529e07e9 100644
--- a/src/cmd/pack/doc.go
+++ b/src/cmd/pack/doc.go
@@ -1,29 +1,37 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build ignore
-
/*
-Pack is a variant of the Plan 9 ar tool. The original is documented at
+Pack is a simple version of the traditional Unix ar tool.
+It implements only the operations needed by Go.
- http://plan9.bell-labs.com/magic/man2html/1/ar
+Usage:
+ go tool pack op file.a [name...]
-It adds a special Go-specific section __.PKGDEF that collects all the
-Go type information from the files in the archive; that section is
-used by the compiler when importing the package during compilation.
+Pack applies the operation to the archive, using the names as arguments to the operation.
-Usage:
- go tool pack [uvnbailogS][mrxtdpq][P prefix] archive files ...
+The operation op is given by one of these letters:
+
+ c append files (from the file system) to a new archive
+ p print files from the archive
+ r append files (from the file system) to the archive
+ t list files from the archive
+ x extract files from the archive
+
+For the p, t, and x commands, listing no names on the command line
+causes the operation to apply to all files in the archive.
-The new option 'g' causes pack to maintain the __.PKGDEF section
-as files are added to the archive.
+In contrast to Unix ar, the r operation always appends to the archive,
+even if a file with the given name already exists in the archive. In this way
+pack's r operation is more like Unix ar's rq operation.
-The new option 'S' forces pack to mark the archive as safe.
+Adding the letter v to an operation, as in pv or rv, enables verbose operation:
+For the c and r commands, names are printed as files are added.
+For the p command, each file is prefixed by the name on a line by itself.
+For the t command, the listing includes additional file metadata.
+For the x command, names are printed as files are extracted.
-The new option 'P' causes pack to remove the given prefix
-from file names in the line number information in object files
-that are already stored in or added to the archive.
*/
package main
diff --git a/src/cmd/pack/pack.go b/src/cmd/pack/pack.go
new file mode 100644
index 000000000..594433712
--- /dev/null
+++ b/src/cmd/pack/pack.go
@@ -0,0 +1,486 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+)
+
+/*
+The archive format is:
+
+First, on a line by itself
+ !<arch>
+
+Then zero or more file records. Each file record has a fixed-size one-line header
+followed by data bytes followed by an optional padding byte. The header is:
+
+ %-16s%-12d%-6d%-6d%-8o%-10d`
+ name mtime uid gid mode size
+
+(note the trailing backquote). The %-16s here means at most 16 *bytes* of
+the name, and if shorter, space padded on the right.
+*/
+
+const usageMessage = `Usage: pack op file.a [name....]
+Where op is one of cprtx optionally followed by v for verbose output.
+For compatibility with old Go build environments the op string grc is
+accepted as a synonym for c.
+
+For more information, run
+ godoc cmd/pack`
+
+func usage() {
+ fmt.Fprintln(os.Stderr, usageMessage)
+ os.Exit(2)
+}
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("pack: ")
+ // need "pack op archive" at least.
+ if len(os.Args) < 3 {
+ log.Print("not enough arguments")
+ fmt.Fprintln(os.Stderr)
+ usage()
+ }
+ setOp(os.Args[1])
+ var ar *Archive
+ switch op {
+ case 'p':
+ ar = archive(os.Args[2], os.O_RDONLY, os.Args[3:])
+ ar.scan(ar.printContents)
+ case 'r':
+ ar = archive(os.Args[2], os.O_RDWR, os.Args[3:])
+ ar.scan(ar.skipContents)
+ ar.addFiles()
+ case 'c':
+ ar = archive(os.Args[2], os.O_RDWR|os.O_TRUNC, os.Args[3:])
+ ar.addPkgdef()
+ ar.addFiles()
+ case 't':
+ ar = archive(os.Args[2], os.O_RDONLY, os.Args[3:])
+ ar.scan(ar.tableOfContents)
+ case 'x':
+ ar = archive(os.Args[2], os.O_RDONLY, os.Args[3:])
+ ar.scan(ar.extractContents)
+ default:
+ log.Printf("invalid operation %q", os.Args[1])
+ fmt.Fprintln(os.Stderr)
+ usage()
+ }
+ if len(ar.files) > 0 {
+ log.Fatalf("file %q not in archive", ar.files[0])
+ }
+}
+
+// The unusual ancestry means the arguments are not Go-standard.
+// These variables hold the decoded operation specified by the first argument.
+// op holds the operation we are doing (prtx).
+// verbose tells whether the 'v' option was specified.
+var (
+ op rune
+ verbose bool
+)
+
+// setOp parses the operation string (first argument).
+func setOp(arg string) {
+ // Recognize 'go tool pack grc' because that was the
+ // formerly canonical way to build a new archive
+ // from a set of input files. Accepting it keeps old
+ // build systems working with both Go 1.2 and Go 1.3.
+ if arg == "grc" {
+ arg = "c"
+ }
+
+ for _, r := range arg {
+ switch r {
+ case 'c', 'p', 'r', 't', 'x':
+ if op != 0 {
+ // At most one can be set.
+ usage()
+ }
+ op = r
+ case 'v':
+ if verbose {
+ // Can be set only once.
+ usage()
+ }
+ verbose = true
+ default:
+ usage()
+ }
+ }
+}
+
+const (
+ arHeader = "!<arch>\n"
+ entryHeader = "%s%-12d%-6d%-6d%-8o%-10d`\n"
+ // In entryHeader the first entry, the name, is always printed as 16 bytes right-padded.
+ entryLen = 16 + 12 + 6 + 6 + 8 + 10 + 1 + 1
+ timeFormat = "Jan _2 15:04 2006"
+)
+
+// An Archive represents an open archive file. It is always scanned sequentially
+// from start to end, without backing up.
+type Archive struct {
+ fd *os.File // Open file descriptor.
+ files []string // Explicit list of files to be processed.
+ pad int // Padding bytes required at end of current archive file
+ matchAll bool // match all files in archive
+}
+
+// archive opens (or if necessary creates) the named archive.
+func archive(name string, mode int, files []string) *Archive {
+ fd, err := os.OpenFile(name, mode, 0)
+ if err != nil && mode&^os.O_TRUNC == os.O_RDWR && os.IsNotExist(err) {
+ fd, err = create(name)
+ }
+ if err != nil {
+ log.Fatal(err)
+ }
+ mustBeArchive(fd)
+ return &Archive{
+ fd: fd,
+ files: files,
+ matchAll: len(files) == 0,
+ }
+}
+
+// create creates and initializes an archive that does not exist.
+func create(name string) (*os.File, error) {
+ fd, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ return nil, err
+ }
+ fmt.Fprint(fd, arHeader)
+ fd.Seek(0, 0)
+ return fd, nil
+}
+
+// mustBeArchive verifies the header of the file. It assumes the file offset
+// is 0 coming in, and leaves it positioned immediately after the header.
+func mustBeArchive(fd *os.File) {
+ buf := make([]byte, len(arHeader))
+ _, err := io.ReadFull(fd, buf)
+ if err != nil || string(buf) != arHeader {
+ log.Fatal("file is not an archive: bad header")
+ }
+}
+
+// An Entry is the internal representation of the per-file header information of one entry in the archive.
+type Entry struct {
+ name string
+ mtime int64
+ uid int
+ gid int
+ mode os.FileMode
+ size int64
+}
+
+func (e *Entry) String() string {
+ return fmt.Sprintf("%s %6d/%-6d %12d %s %s",
+ (e.mode & 0777).String(),
+ e.uid,
+ e.gid,
+ e.size,
+ time.Unix(e.mtime, 0).Format(timeFormat),
+ e.name)
+}
+
+// readMetadata reads and parses the metadata for the next entry in the archive.
+func (ar *Archive) readMetadata() *Entry {
+ buf := make([]byte, entryLen)
+ _, err := io.ReadFull(ar.fd, buf)
+ if err == io.EOF {
+ // No entries left.
+ return nil
+ }
+ if err != nil || buf[entryLen-2] != '`' || buf[entryLen-1] != '\n' {
+ log.Fatal("file is not an archive: bad entry")
+ }
+ entry := new(Entry)
+ entry.name = strings.TrimRight(string(buf[:16]), " ")
+ if len(entry.name) == 0 {
+ log.Fatal("file is not an archive: bad name")
+ }
+ buf = buf[16:]
+ str := string(buf)
+ get := func(width, base, bitsize int) int64 {
+ v, err := strconv.ParseInt(strings.TrimRight(str[:width], " "), base, bitsize)
+ if err != nil {
+ log.Fatal("file is not an archive: bad number in entry: ", err)
+ }
+ str = str[width:]
+ return v
+ }
+ // %-16s%-12d%-6d%-6d%-8o%-10d`
+ entry.mtime = get(12, 10, 64)
+ entry.uid = int(get(6, 10, 32))
+ entry.gid = int(get(6, 10, 32))
+ entry.mode = os.FileMode(get(8, 8, 32))
+ entry.size = get(10, 10, 64)
+ return entry
+}
+
+// scan scans the archive and executes the specified action on each entry.
+// When action returns, the file offset is at the start of the next entry.
+func (ar *Archive) scan(action func(*Entry)) {
+ for {
+ entry := ar.readMetadata()
+ if entry == nil {
+ break
+ }
+ action(entry)
+ }
+}
+
+// listEntry prints to standard output a line describing the entry.
+func listEntry(ar *Archive, entry *Entry, verbose bool) {
+ if verbose {
+ fmt.Fprintf(stdout, "%s\n", entry)
+ } else {
+ fmt.Fprintf(stdout, "%s\n", entry.name)
+ }
+}
+
+// output copies the entry to the specified writer.
+func (ar *Archive) output(entry *Entry, w io.Writer) {
+ n, err := io.Copy(w, io.LimitReader(ar.fd, entry.size))
+ if err != nil {
+ log.Fatal(err)
+ }
+ if n != entry.size {
+ log.Fatal("short file")
+ }
+ if entry.size&1 == 1 {
+ _, err := ar.fd.Seek(1, 1)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+}
+
+// skip skips the entry without reading it.
+func (ar *Archive) skip(entry *Entry) {
+ size := entry.size
+ if size&1 == 1 {
+ size++
+ }
+ _, err := ar.fd.Seek(size, 1)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+// match reports whether the entry matches the argument list.
+// If it does, it also drops the file from the to-be-processed list.
+func (ar *Archive) match(entry *Entry) bool {
+ if ar.matchAll {
+ return true
+ }
+ for i, name := range ar.files {
+ if entry.name == name {
+ copy(ar.files[i:], ar.files[i+1:])
+ ar.files = ar.files[:len(ar.files)-1]
+ return true
+ }
+ }
+ return false
+}
+
+// addFiles adds files to the archive. The archive is known to be
+// sane and we are positioned at the end. No attempt is made
+// to check for existing files.
+func (ar *Archive) addFiles() {
+ if len(ar.files) == 0 {
+ usage()
+ }
+ for _, file := range ar.files {
+ if verbose {
+ fmt.Printf("%s\n", file)
+ }
+ fd, err := os.Open(file)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ar.addFile(fd)
+ }
+ ar.files = nil
+}
+
+// FileLike abstracts the few methods we need, so we can test without needing real files.
+type FileLike interface {
+ Name() string
+ Stat() (os.FileInfo, error)
+ Read([]byte) (int, error)
+ Close() error
+}
+
+// addFile adds a single file to the archive
+func (ar *Archive) addFile(fd FileLike) {
+ defer fd.Close()
+ // Format the entry.
+ // First, get its info.
+ info, err := fd.Stat()
+ if err != nil {
+ log.Fatal(err)
+ }
+ // mtime, uid, gid are all zero so repeated builds produce identical output.
+ mtime := int64(0)
+ uid := 0
+ gid := 0
+ ar.startFile(info.Name(), mtime, uid, gid, info.Mode(), info.Size())
+ n64, err := io.Copy(ar.fd, fd)
+ if err != nil {
+ log.Fatal("writing file: ", err)
+ }
+ if n64 != info.Size() {
+ log.Fatalf("writing file: wrote %d bytes; file is size %d", n64, info.Size())
+ }
+ ar.endFile()
+}
+
+// startFile writes the archive entry header.
+func (ar *Archive) startFile(name string, mtime int64, uid, gid int, mode os.FileMode, size int64) {
+ n, err := fmt.Fprintf(ar.fd, entryHeader, exactly16Bytes(name), mtime, uid, gid, mode, size)
+ if err != nil || n != entryLen {
+ log.Fatal("writing entry header: ", err)
+ }
+ ar.pad = int(size & 1)
+}
+
+// endFile writes the archive entry tail (a single byte of padding, if the file size was odd).
+func (ar *Archive) endFile() {
+ if ar.pad != 0 {
+ _, err := ar.fd.Write([]byte{0})
+ if err != nil {
+ log.Fatal("writing archive: ", err)
+ }
+ ar.pad = 0
+ }
+}
+
+// addPkgdef adds the __.PKGDEF file to the archive, copied
+// from the first Go object file on the file list, if any.
+// The archive is known to be empty.
+func (ar *Archive) addPkgdef() {
+ for _, file := range ar.files {
+ pkgdef, err := readPkgdef(file)
+ if err != nil {
+ continue
+ }
+ if verbose {
+ fmt.Printf("__.PKGDEF # %s\n", file)
+ }
+ ar.startFile("__.PKGDEF", 0, 0, 0, 0644, int64(len(pkgdef)))
+ _, err = ar.fd.Write(pkgdef)
+ if err != nil {
+ log.Fatal("writing __.PKGDEF: ", err)
+ }
+ ar.endFile()
+ break
+ }
+}
+
+// readPkgdef extracts the __.PKGDEF data from a Go object file.
+func readPkgdef(file string) (data []byte, err error) {
+ f, err := os.Open(file)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ // Read from file, collecting header for __.PKGDEF.
+ // The header is from the beginning of the file until a line
+ // containing just "!". The first line must begin with "go object ".
+ rbuf := bufio.NewReader(f)
+ var wbuf bytes.Buffer
+ for {
+ line, err := rbuf.ReadBytes('\n')
+ if err != nil {
+ return nil, err
+ }
+ if wbuf.Len() == 0 && !bytes.HasPrefix(line, []byte("go object ")) {
+ return nil, errors.New("not a Go object file")
+ }
+ if bytes.Equal(line, []byte("!\n")) {
+ break
+ }
+ wbuf.Write(line)
+ }
+ return wbuf.Bytes(), nil
+}
+
+// exactly16Bytes truncates the string if necessary so it is at most 16 bytes long,
+// then pads the result with spaces to be exactly 16 bytes.
+// Fmt uses runes for its width calculation, but we need bytes in the entry header.
+func exactly16Bytes(s string) string {
+ for len(s) > 16 {
+ _, wid := utf8.DecodeLastRuneInString(s)
+ s = s[:len(s)-wid]
+ }
+ const sixteenSpaces = " "
+ s += sixteenSpaces[:16-len(s)]
+ return s
+}
+
+// Finally, the actual commands. Each is an action.
+
+// can be modified for testing.
+var stdout io.Writer = os.Stdout
+
+// printContents implements the 'p' command.
+func (ar *Archive) printContents(entry *Entry) {
+ if ar.match(entry) {
+ if verbose {
+ listEntry(ar, entry, false)
+ }
+ ar.output(entry, stdout)
+ } else {
+ ar.skip(entry)
+ }
+}
+
+// skipContents implements the first part of the 'r' command.
+// It just scans the archive to make sure it's intact.
+func (ar *Archive) skipContents(entry *Entry) {
+ ar.skip(entry)
+}
+
+// tableOfContents implements the 't' command.
+func (ar *Archive) tableOfContents(entry *Entry) {
+ if ar.match(entry) {
+ listEntry(ar, entry, verbose)
+ }
+ ar.skip(entry)
+}
+
+// extractContents implements the 'x' command.
+func (ar *Archive) extractContents(entry *Entry) {
+ if ar.match(entry) {
+ if verbose {
+ listEntry(ar, entry, false)
+ }
+ fd, err := os.OpenFile(entry.name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, entry.mode)
+ if err != nil {
+ log.Fatal(err)
+ }
+ ar.output(entry, fd)
+ fd.Close()
+ } else {
+ ar.skip(entry)
+ }
+}
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
new file mode 100644
index 000000000..486242603
--- /dev/null
+++ b/src/cmd/pack/pack_test.go
@@ -0,0 +1,402 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "testing"
+ "time"
+ "unicode/utf8"
+)
+
+func TestExactly16Bytes(t *testing.T) {
+ var tests = []string{
+ "",
+ "a",
+ "日本語",
+ "1234567890123456",
+ "12345678901234567890",
+ "1234567890123本語4567890",
+ "12345678901234日本語567890",
+ "123456789012345日本語67890",
+ "1234567890123456日本語7890",
+ "1234567890123456日本語7日本語890",
+ }
+ for _, str := range tests {
+ got := exactly16Bytes(str)
+ if len(got) != 16 {
+ t.Errorf("exactly16Bytes(%q) is %q, length %d", str, got, len(got))
+ }
+ // Make sure it is full runes.
+ for _, c := range got {
+ if c == utf8.RuneError {
+ t.Errorf("exactly16Bytes(%q) is %q, has partial rune", str, got)
+ }
+ }
+ }
+}
+
+// tmpDir creates a temporary directory and returns its name.
+func tmpDir(t *testing.T) string {
+ name, err := ioutil.TempDir("", "pack")
+ if err != nil {
+ t.Fatal(err)
+ }
+ return name
+}
+
+// Test that we can create an archive, write to it, and get the same contents back.
+// Tests the rv and then the pv command on a new archive.
+func TestCreate(t *testing.T) {
+ dir := tmpDir(t)
+ defer os.RemoveAll(dir)
+ name := filepath.Join(dir, "pack.a")
+ ar := archive(name, os.O_RDWR, nil)
+ // Add an entry by hand.
+ ar.addFile(helloFile.Reset())
+ ar.fd.Close()
+ // Now check it.
+ ar = archive(name, os.O_RDONLY, []string{helloFile.name})
+ var buf bytes.Buffer
+ stdout = &buf
+ verbose = true
+ defer func() {
+ stdout = os.Stdout
+ verbose = false
+ }()
+ ar.scan(ar.printContents)
+ ar.fd.Close()
+ result := buf.String()
+ // Expect verbose output plus file contents.
+ expect := fmt.Sprintf("%s\n%s", helloFile.name, helloFile.contents)
+ if result != expect {
+ t.Fatalf("expected %q got %q", expect, result)
+ }
+}
+
+// Test that we can create an archive, put some files in it, and get back a correct listing.
+// Tests the tv command.
+func TestTableOfContents(t *testing.T) {
+ dir := tmpDir(t)
+ defer os.RemoveAll(dir)
+ name := filepath.Join(dir, "pack.a")
+ ar := archive(name, os.O_RDWR, nil)
+
+ // Add some entries by hand.
+ ar.addFile(helloFile.Reset())
+ ar.addFile(goodbyeFile.Reset())
+ ar.fd.Close()
+
+ // Now print it.
+ ar = archive(name, os.O_RDONLY, nil)
+ var buf bytes.Buffer
+ stdout = &buf
+ verbose = true
+ defer func() {
+ stdout = os.Stdout
+ verbose = false
+ }()
+ ar.scan(ar.tableOfContents)
+ ar.fd.Close()
+ result := buf.String()
+ // Expect verbose listing.
+ expect := fmt.Sprintf("%s\n%s\n", helloFile.Entry(), goodbyeFile.Entry())
+ if result != expect {
+ t.Fatalf("expected %q got %q", expect, result)
+ }
+
+ // Do it again without verbose.
+ verbose = false
+ buf.Reset()
+ ar = archive(name, os.O_RDONLY, nil)
+ ar.scan(ar.tableOfContents)
+ ar.fd.Close()
+ result = buf.String()
+ // Expect non-verbose listing.
+ expect = fmt.Sprintf("%s\n%s\n", helloFile.name, goodbyeFile.name)
+ if result != expect {
+ t.Fatalf("expected %q got %q", expect, result)
+ }
+
+ // Do it again with file list arguments.
+ verbose = false
+ buf.Reset()
+ ar = archive(name, os.O_RDONLY, []string{helloFile.name})
+ ar.scan(ar.tableOfContents)
+ ar.fd.Close()
+ result = buf.String()
+ // Expect only helloFile.
+ expect = fmt.Sprintf("%s\n", helloFile.name)
+ if result != expect {
+ t.Fatalf("expected %q got %q", expect, result)
+ }
+}
+
+// Test that we can create an archive, put some files in it, and get back a file.
+// Tests the x command.
+func TestExtract(t *testing.T) {
+ dir := tmpDir(t)
+ defer os.RemoveAll(dir)
+ name := filepath.Join(dir, "pack.a")
+ ar := archive(name, os.O_RDWR, nil)
+ // Add some entries by hand.
+ ar.addFile(helloFile.Reset())
+ ar.addFile(goodbyeFile.Reset())
+ ar.fd.Close()
+ // Now extract one file. We chdir to the directory of the archive for simplicity.
+ pwd, err := os.Getwd()
+ if err != nil {
+ t.Fatal("os.Getwd: ", err)
+ }
+ err = os.Chdir(dir)
+ if err != nil {
+ t.Fatal("os.Chdir: ", err)
+ }
+ defer func() {
+ err := os.Chdir(pwd)
+ if err != nil {
+ t.Fatal("os.Chdir: ", err)
+ }
+ }()
+ ar = archive(name, os.O_RDONLY, []string{goodbyeFile.name})
+ ar.scan(ar.extractContents)
+ ar.fd.Close()
+ data, err := ioutil.ReadFile(goodbyeFile.name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Expect contents of file.
+ result := string(data)
+ expect := goodbyeFile.contents
+ if result != expect {
+ t.Fatalf("expected %q got %q", expect, result)
+ }
+}
+
+// Test that pack-created archives can be understood by the tools.
+func TestHello(t *testing.T) {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ dir := tmpDir(t)
+ defer os.RemoveAll(dir)
+ hello := filepath.Join(dir, "hello.go")
+ prog := `
+ package main
+ func main() {
+ println("hello world")
+ }
+ `
+ err := ioutil.WriteFile(hello, []byte(prog), 0666)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ char := findChar(t, dir)
+
+ run := func(args ...string) string {
+ return doRun(t, dir, args...)
+ }
+
+ run("go", "build", "cmd/pack") // writes pack binary to dir
+ run("go", "tool", char+"g", "hello.go")
+ run("./pack", "grc", "hello.a", "hello."+char)
+ run("go", "tool", char+"l", "-o", "a.out", "hello.a")
+ out := run("./a.out")
+ if out != "hello world\n" {
+ t.Fatalf("incorrect output: %q, want %q", out, "hello world\n")
+ }
+}
+
+// Test that pack works with very long lines in PKGDEF.
+func TestLargeDefs(t *testing.T) {
+ if runtime.GOOS == "nacl" {
+ t.Skip("skipping on nacl")
+ }
+
+ dir := tmpDir(t)
+ defer os.RemoveAll(dir)
+ large := filepath.Join(dir, "large.go")
+ f, err := os.Create(large)
+ if err != nil {
+ t.Fatal(err)
+ }
+ b := bufio.NewWriter(f)
+
+ printf := func(format string, args ...interface{}) {
+ _, err := fmt.Fprintf(b, format, args...)
+ if err != nil {
+ t.Fatalf("Writing to %s: %v", large, err)
+ }
+ }
+
+ printf("package large\n\ntype T struct {\n")
+ for i := 0; i < 10000; i++ {
+ printf("f%d int `tag:\"", i)
+ for j := 0; j < 100; j++ {
+ printf("t%d=%d,", j, j)
+ }
+ printf("\"`\n")
+ }
+ printf("}\n")
+ if err = b.Flush(); err != nil {
+ t.Fatal(err)
+ }
+ if err = f.Close(); err != nil {
+ t.Fatal(err)
+ }
+
+ main := filepath.Join(dir, "main.go")
+ prog := `
+ package main
+ import "large"
+ var V large.T
+ func main() {
+ println("ok")
+ }
+ `
+ err = ioutil.WriteFile(main, []byte(prog), 0666)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ char := findChar(t, dir)
+
+ run := func(args ...string) string {
+ return doRun(t, dir, args...)
+ }
+
+ run("go", "build", "cmd/pack") // writes pack binary to dir
+ run("go", "tool", char+"g", "large.go")
+ run("./pack", "grc", "large.a", "large."+char)
+ run("go", "tool", char+"g", "-I", ".", "main.go")
+ run("go", "tool", char+"l", "-L", ".", "-o", "a.out", "main."+char)
+ out := run("./a.out")
+ if out != "ok\n" {
+ t.Fatalf("incorrect output: %q, want %q", out, "ok\n")
+ }
+}
+
+// doRun runs a program in a directory and returns the output.
+func doRun(t *testing.T, dir string, args ...string) string {
+ cmd := exec.Command(args[0], args[1:]...)
+ cmd.Dir = dir
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("%v: %v\n%s", args, err, string(out))
+ }
+ return string(out)
+}
+
+// findChar returns the architecture character for the go command.
+func findChar(t *testing.T, dir string) string {
+ out := doRun(t, dir, "go", "env")
+ re, err := regexp.Compile(`\s*GOCHAR=['"]?(\w)['"]?`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fields := re.FindStringSubmatch(out)
+ if fields == nil {
+ t.Fatal("cannot find GOCHAR in 'go env' output:\n", out)
+ }
+ return fields[1]
+}
+
+// Fake implementation of files.
+
+var helloFile = &FakeFile{
+ name: "hello",
+ contents: "hello world", // 11 bytes, an odd number.
+ mode: 0644,
+}
+
+var goodbyeFile = &FakeFile{
+ name: "goodbye",
+ contents: "Sayonara, Jim", // 13 bytes, another odd number.
+ mode: 0644,
+}
+
+// FakeFile implements FileLike and also os.FileInfo.
+type FakeFile struct {
+ name string
+ contents string
+ mode os.FileMode
+ offset int
+}
+
+// Reset prepares a FakeFile for reuse.
+func (f *FakeFile) Reset() *FakeFile {
+ f.offset = 0
+ return f
+}
+
+// FileLike methods.
+
+func (f *FakeFile) Name() string {
+ // A bit of a cheat: we only have a basename, so that's also ok for FileInfo.
+ return f.name
+}
+
+func (f *FakeFile) Stat() (os.FileInfo, error) {
+ return f, nil
+}
+
+func (f *FakeFile) Read(p []byte) (int, error) {
+ if f.offset >= len(f.contents) {
+ return 0, io.EOF
+ }
+ n := copy(p, f.contents[f.offset:])
+ f.offset += n
+ return n, nil
+}
+
+func (f *FakeFile) Close() error {
+ return nil
+}
+
+// os.FileInfo methods.
+
+func (f *FakeFile) Size() int64 {
+ return int64(len(f.contents))
+}
+
+func (f *FakeFile) Mode() os.FileMode {
+ return f.mode
+}
+
+func (f *FakeFile) ModTime() time.Time {
+ return time.Time{}
+}
+
+func (f *FakeFile) IsDir() bool {
+ return false
+}
+
+func (f *FakeFile) Sys() interface{} {
+ return nil
+}
+
+// Special helpers.
+
+func (f *FakeFile) Entry() *Entry {
+ return &Entry{
+ name: f.name,
+ mtime: 0, // Defined to be zero.
+ uid: 0, // Ditto.
+ gid: 0, // Ditto.
+ mode: f.mode,
+ size: int64(len(f.contents)),
+ }
+}
diff --git a/src/cmd/yacc/Makefile b/src/cmd/yacc/Makefile
index 480844805..f8c8169bd 100644
--- a/src/cmd/yacc/Makefile
+++ b/src/cmd/yacc/Makefile
@@ -2,9 +2,11 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-expr: yacc.go expr.y
+TARG=expr$(shell go env GOEXE)
+
+$(TARG): yacc.go expr.y
go run yacc.go -p expr expr.y
- go build -o expr y.go
+ go build -o $(TARG) y.go
clean:
- rm -f y.go y.output expr
+ rm -f y.go y.output $(TARG)
diff --git a/src/cmd/yacc/expr.y b/src/cmd/yacc/expr.y
index 3afffe7ee..77e9259da 100644
--- a/src/cmd/yacc/expr.y
+++ b/src/cmd/yacc/expr.y
@@ -125,7 +125,7 @@ func (x *exprLex) Lex(yylval *exprSymType) int {
case '÷':
return '/'
- case ' ', '\t', '\n':
+ case ' ', '\t', '\n', '\r':
default:
log.Printf("unrecognized character %q", c)
}
diff --git a/src/cmd/yacc/yacc.go b/src/cmd/yacc/yacc.go
index c53dc3b74..c53403266 100644
--- a/src/cmd/yacc/yacc.go
+++ b/src/cmd/yacc/yacc.go
@@ -49,6 +49,8 @@ import (
"bytes"
"flag"
"fmt"
+ "go/format"
+ "io/ioutil"
"os"
"strings"
"unicode"
@@ -3212,6 +3214,7 @@ func exit(status int) {
if ftable != nil {
ftable.Flush()
ftable = nil
+ gofmt()
}
if foutput != nil {
foutput.Flush()
@@ -3224,6 +3227,18 @@ func exit(status int) {
os.Exit(status)
}
+func gofmt() {
+ src, err := ioutil.ReadFile(oflag)
+ if err != nil {
+ return
+ }
+ src, err = format.Source(src)
+ if err != nil {
+ return
+ }
+ ioutil.WriteFile(oflag, src, 0666)
+}
+
var yaccpar string // will be processed version of yaccpartext: s/$$/prefix/g
var yaccpartext = `
/* parser for yacc output */