summaryrefslogtreecommitdiff
path: root/sys/src/cmd/7a
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-04-08 13:45:49 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-04-08 13:45:49 +0200
commitb29d5ac7b1f713e41285ad4b2ce1b23313d8088e (patch)
tree08397fd124d2b3881189599c114e74c777771f87 /sys/src/cmd/7a
parente897df33e638dcc3768b8207146e2a4195dd3c4b (diff)
add arm64 c compiler and assembler (thanks charles forsyth)
this is the the initial sync of charles forsyths plan9 c compiler suite from http://bitbucket.org/plan9-from-bell-labs/9-cc at changeset version 54:65fb8bb56c59
Diffstat (limited to 'sys/src/cmd/7a')
-rw-r--r--sys/src/cmd/7a/a.h185
-rw-r--r--sys/src/cmd/7a/a.y878
-rw-r--r--sys/src/cmd/7a/lex.c1041
-rw-r--r--sys/src/cmd/7a/mkfile19
4 files changed, 2123 insertions, 0 deletions
diff --git a/sys/src/cmd/7a/a.h b/sys/src/cmd/7a/a.h
new file mode 100644
index 000000000..5d09f6270
--- /dev/null
+++ b/sys/src/cmd/7a/a.h
@@ -0,0 +1,185 @@
+/*
+ * arm64
+ */
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "../7c/7.out.h"
+
+typedef vlong int64;
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+typedef struct Sym Sym;
+typedef struct Gen Gen;
+typedef struct Io Io;
+typedef struct Hist Hist;
+
+#define MAXALIGN 7
+#define FPCHIP 1
+#define NSYMB 8192
+#define BUFSIZ 8192
+#define HISTSZ 20
+#define NINCLUDE 10
+#define NHUNK 10000
+#define EOF (-1)
+#define IGN (-2)
+#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
+#define NHASH 503
+#define STRINGSZ 200
+#define NMACRO 10
+
+struct Sym
+{
+ Sym* link;
+ char* macro;
+ long value;
+ ushort type;
+ char *name;
+ char sym;
+};
+#define S ((Sym*)0)
+
+EXTERN struct
+{
+ char* p;
+ int c;
+} fi;
+
+struct Io
+{
+ Io* link;
+ char b[BUFSIZ];
+ char* p;
+ short c;
+ short f;
+};
+#define I ((Io*)0)
+
+EXTERN struct
+{
+ Sym* sym;
+ short type;
+} h[NSYM];
+
+struct Gen
+{
+ Sym* sym;
+ int64 offset;
+ short type;
+ short reg;
+ short xreg;
+ short name;
+ short ext;
+ double dval;
+ char sval[NSNAME];
+};
+
+struct Hist
+{
+ Hist* link;
+ char* name;
+ long line;
+ long offset;
+};
+#define H ((Hist*)0)
+
+enum
+{
+ CLAST,
+ CMACARG,
+ CMACRO,
+ CPREPROC,
+};
+
+EXTERN char debug[256];
+EXTERN Sym* hash[NHASH];
+EXTERN char* Dlist[30];
+EXTERN int nDlist;
+EXTERN Hist* ehist;
+EXTERN int newflag;
+EXTERN Hist* hist;
+EXTERN char* hunk;
+EXTERN char* include[NINCLUDE];
+EXTERN Io* iofree;
+EXTERN Io* ionext;
+EXTERN Io* iostack;
+EXTERN long lineno;
+EXTERN int nerrors;
+EXTERN long nhunk;
+EXTERN int ninclude;
+EXTERN Gen nullgen;
+EXTERN char* outfile;
+EXTERN int pass;
+EXTERN char* pathname;
+EXTERN long pc;
+EXTERN int peekc;
+EXTERN int sym;
+EXTERN char symb[NSYMB];
+EXTERN int thechar;
+EXTERN char* thestring;
+EXTERN long thunk;
+EXTERN Biobuf obuf;
+
+void* alloc(long);
+void* allocn(void*, long, long);
+void errorexit(void);
+void pushio(void);
+void newio(void);
+void newfile(char*, int);
+Sym* slookup(char*);
+Sym* lookup(void);
+void syminit(Sym*);
+long yylex(void);
+int getc(void);
+int getnsc(void);
+void unget(int);
+int escchar(int);
+void cinit(void);
+void pinit(char*);
+void cclean(void);
+void outcode(int, Gen*, int, Gen*);
+void outcodec(int, int, Gen*, int, Gen*);
+void outcode4(int, Gen*, int, Gen*, Gen*);
+void zname(char*, int, int);
+void zaddr(Gen*, int);
+void ieeedtod(Ieee*, double);
+int filbuf(void);
+Sym* getsym(void);
+void domacro(void);
+void macund(void);
+void macdef(void);
+void macexpand(Sym*, char*);
+void macinc(void);
+void maclin(void);
+void macprag(void);
+void macif(int);
+void macend(void);
+void outhist(void);
+void dodefine(char*);
+void prfile(long);
+void linehist(char*, int);
+void gethunk(void);
+void yyerror(char*, ...);
+int yyparse(void);
+void setinclude(char*);
+int assemble(char*);
+
+/*
+ * system-dependent stuff from ../cc/compat.c
+ */
+
+enum /* keep in synch with ../cc/cc.h */
+{
+ Plan9 = 1<<0,
+ Unix = 1<<1,
+ Windows = 1<<2,
+};
+int mywait(int*);
+int mycreat(char*, int);
+int systemtype(int);
+int pathchar(void);
+int myfork(void);
+void* mysbrk(ulong);
diff --git a/sys/src/cmd/7a/a.y b/sys/src/cmd/7a/a.y
new file mode 100644
index 000000000..ef82767f7
--- /dev/null
+++ b/sys/src/cmd/7a/a.y
@@ -0,0 +1,878 @@
+%{
+#include "a.h"
+%}
+%union
+{
+ Sym *sym;
+ vlong lval;
+ double dval;
+ char sval[NSNAME];
+ Gen gen;
+}
+%left '|'
+%left '^'
+%left '&'
+%left '<' '>'
+%left '+' '-'
+%left '*' '/' '%'
+%token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
+%token <lval> LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
+%token <lval> LTYPEB LTYPEC LTYPED LTYPEE LTYPEF
+%token <lval> LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
+%token <lval> LTYPEL LTYPEM LTYPEN LTYPEO LTYPEP LTYPEQ
+%token <lval> LTYPER LTYPES LTYPET LTYPEU LTYPEV LTYPEW LTYPEX LTYPEY LTYPEZ
+%token <lval> LMOVK LDMB LSTXR
+%token <lval> LCONST LSP LSB LFP LPC
+%token <lval> LR LREG LF LFREG LV LVREG LC LCREG LFCR LFCSEL
+%token <lval> LCOND LS LAT LEXT LSPR LSPREG LVTYPE
+%token <dval> LFCONST
+%token <sval> LSCONST
+%token <sym> LNAME LLAB LVAR
+%type <lval> con expr pointer offset sreg spreg
+%type <lval> scon indexreg vset vreglist
+%type <gen> gen rel reg freg vreg shift fcon frcon extreg vlane vgen
+%type <gen> imm ximm name oreg nireg ioreg imsr spr cond sysarg
+%%
+prog:
+| prog line
+
+line:
+ LLAB ':'
+ {
+ if($1->value != pc)
+ yyerror("redeclaration of %s", $1->name);
+ $1->value = pc;
+ }
+ line
+| LNAME ':'
+ {
+ $1->type = LLAB;
+ $1->value = pc;
+ }
+ line
+| LNAME '=' expr ';'
+ {
+ $1->type = LVAR;
+ $1->value = $3;
+ }
+| LVAR '=' expr ';'
+ {
+ if($1->value != $3)
+ yyerror("redeclaration of %s", $1->name);
+ $1->value = $3;
+ }
+| ';'
+| inst ';'
+| error ';'
+
+inst:
+/*
+ * ERET
+ */
+ LTYPE0 comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+/*
+ * ADD
+ */
+| LTYPE1 imsr ',' spreg ',' reg
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LTYPE1 imsr ',' spreg ','
+ {
+ outcode($1, &$2, $4, &nullgen);
+ }
+| LTYPE1 imsr ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * CLS
+ */
+| LTYPE2 imsr ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * MOV
+ */
+| LTYPE3 gen ',' gen
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * MOVK
+ */
+| LMOVK imm ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVK imm '<' '<' con ',' reg
+ {
+ Gen g;
+ g = nullgen;
+ g.type = D_CONST;
+ g.offset = $5;
+ outcode4($1, &$2, NREG, &g, &$7);
+ }
+/*
+ * B/BL
+ */
+| LTYPE4 comma rel
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+| LTYPE4 comma nireg
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+/*
+ * BEQ
+ */
+| LTYPE5 comma rel
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+/*
+ * SVC
+ */
+| LTYPE6 comma gen
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+| LTYPE6
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+/*
+ * CMP
+ */
+| LTYPE7 imsr ',' spreg comma
+ {
+ outcode($1, &$2, $4, &nullgen);
+ }
+/*
+ * CBZ
+ */
+| LTYPE8 reg ',' rel
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * CSET
+ */
+| LTYPER cond ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * CSEL/CINC/CNEG/CINV
+ */
+| LTYPES cond ',' reg ',' reg ',' reg
+ {
+ outcode4($1, &$2, $6.reg, &$4, &$8);
+ }
+| LTYPES cond ',' reg ',' reg
+ {
+ outcode($1, &$2, $4.reg, &$6);
+ }
+/*
+ * TBZ
+ */
+| LTYPET imm ',' reg ',' rel
+ {
+ outcode($1, &$2, $4.reg, &$6);
+ }
+/*
+ * CCMN
+ */
+| LTYPEU cond ',' imsr ',' reg ',' imm comma
+ {
+ outcode4($1, &$2, $6.reg, &$4, &$8);
+ }
+/*
+ * ADR
+ */
+| LTYPEV rel ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LTYPEV '$' name ',' reg
+ {
+ outcode($1, &$3, NREG, &$5);
+ }
+/*
+ * BFM/BFI
+ */
+| LTYPEY imm ',' imm ',' spreg ',' reg
+ {
+ outcode4($1, &$2, $6, &$4, &$8);
+ }
+/*
+ * EXTR
+ */
+| LTYPEP imm ',' reg ',' spreg ',' reg
+ {
+ outcode4($1, &$2, $6, &$4, &$8);
+ }
+/*
+ * RET/RETURN
+ */
+| LTYPEA comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+| LTYPEA reg
+ {
+ outcode($1, &nullgen, NREG, &$2);
+ }
+/*
+ * NOP
+ */
+| LTYPEQ comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+| LTYPEQ reg comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LTYPEQ freg comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LTYPEQ ',' reg
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+| LTYPEQ ',' freg
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+/*
+ * TEXT/GLOBL
+ */
+| LTYPEB name ',' imm
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LTYPEB name ',' con ',' imm
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+/*
+ * DATA
+ */
+| LTYPEC name '/' con ',' ximm
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+/*
+ * CASE
+ */
+| LTYPED reg ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * word
+ */
+| LTYPEH comma ximm
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+/*
+ * floating-point
+ */
+| LTYPEI freg ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * FADDD
+ */
+| LTYPEK frcon ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LTYPEK frcon ',' freg ',' freg
+ {
+ outcode($1, &$2, $4.reg, &$6);
+ }
+/*
+ * FCMP
+ */
+| LTYPEL frcon ',' freg comma
+ {
+ outcode($1, &$2, $4.reg, &nullgen);
+ }
+/*
+ * FCCMP
+ */
+| LTYPEF cond ',' freg ',' freg ',' imm comma
+ {
+ outcode4($1, &$2, $6.reg, &$4, &$8);
+ }
+/*
+ * FMULA
+ */
+| LTYPE9 freg ',' freg ', ' freg ',' freg comma
+ {
+ outcode4($1, &$2, $4.reg, &$6, &$8);
+ }
+/*
+ * FCSEL
+ */
+| LFCSEL cond ',' freg ',' freg ',' freg
+ {
+ outcode4($1, &$2, $6.reg, &$4, &$8);
+ }
+/*
+ * SIMD
+ */
+| LTYPEW vgen ',' vgen
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LTYPEW vgen ',' vgen ',' vgen
+ {
+ outcode($1, &$2, $4.reg, &$6);
+ }
+/*
+ * MOVP/MOVNP
+ */
+| LTYPEJ gen ',' sreg ',' gen
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+/*
+ * MADD Rn,Rm,Ra,Rd
+ */
+| LTYPEM reg ',' reg ',' sreg ',' reg
+ {
+ outcode4($1, &$2, $6, &$4, &$8);
+ }
+/*
+ * SYS/SYSL
+ */
+| LTYPEN sysarg
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LTYPEN reg ',' sysarg
+ {
+ outcode($1, &$4, $2.reg, &nullgen);
+ }
+| LTYPEO sysarg ',' reg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * DMB, HINT
+ */
+| LDMB imm
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+/*
+ * STXR
+ */
+| LSTXR reg ',' gen ',' sreg
+ {
+ outcode($1, &$2, $6, &$4);
+ }
+/*
+ * END
+ */
+| LTYPEE comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+
+cond:
+ LCOND
+ {
+ $$ = nullgen;
+ $$.type = D_COND;
+ $$.reg = $1;
+ }
+
+comma:
+| ',' comma
+
+sysarg:
+ con ',' con ',' con ',' con
+ {
+ $$ = nullgen;
+ $$.type = D_CONST;
+ $$.offset = SYSARG4($1, $3, $5, $7);
+ }
+| imm
+
+rel:
+ con '(' LPC ')'
+ {
+ $$ = nullgen;
+ $$.type = D_BRANCH;
+ $$.offset = $1 + pc;
+ }
+| LNAME offset
+ {
+ $$ = nullgen;
+ 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;
+ }
+
+ximm: '$' con
+ {
+ $$ = nullgen;
+ $$.type = D_CONST;
+ $$.offset = $2;
+ }
+| '$' oreg
+ {
+ $$ = $2;
+ $$.type = D_CONST;
+ }
+| '$' '*' '$' oreg
+ {
+ $$ = $4;
+ $$.type = D_OCONST;
+ }
+| '$' LSCONST
+ {
+ $$ = nullgen;
+ $$.type = D_SCONST;
+ memmove($$.sval, $2, sizeof($$.sval));
+ }
+| fcon
+
+fcon:
+ '$' LFCONST
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = $2;
+ }
+| '$' '-' LFCONST
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = -$3;
+ }
+
+gen:
+ reg
+| ximm
+| LFCR
+ {
+ $$ = nullgen;
+ $$.type = D_SPR;
+ $$.offset = $1;
+ }
+| con
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.offset = $1;
+ }
+| oreg
+| freg
+| vreg
+| spr
+
+nireg:
+ '(' sreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.reg = $2;
+ $$.offset = 0;
+ }
+| name
+ {
+ $$ = $1;
+ if($1.name != D_EXTERN && $1.name != D_STATIC) {
+ }
+ }
+
+oreg:
+ name
+| name '(' sreg ')'
+ {
+ $$ = $1;
+ $$.type = D_OREG;
+ $$.reg = $3;
+ }
+| ioreg
+
+ioreg:
+ '(' sreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.reg = $2;
+ $$.offset = 0;
+ }
+| con '(' sreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.reg = $3;
+ $$.offset = $1;
+ }
+| con '(' sreg ')' '!'
+ {
+ $$ = nullgen;
+ $$.type = D_XPRE;
+ $$.reg = $3;
+ $$.offset = $1;
+ }
+| '(' sreg ')' con '!'
+ {
+ $$.type = D_XPOST;
+ $$.offset = $2;
+ }
+| '(' sreg ')' '(' indexreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_ROFF;
+ $$.reg = $2;
+ $$.xreg = $5 & 0x1f;
+ $$.offset = $5;
+ }
+| '(' sreg ')' '[' indexreg ']'
+ {
+ $$ = nullgen;
+ $$.type = D_ROFF;
+ $$.reg = $2;
+ $$.xreg = $5 & 0x1f;
+ $$.offset = $5 | (1<<16);
+ }
+
+imsr:
+ imm
+| shift
+| extreg
+
+imm: '$' con
+ {
+ $$ = nullgen;
+ $$.type = D_CONST;
+ $$.offset = $2;
+ }
+
+reg:
+ sreg
+ {
+ $$ = nullgen;
+ $$.type = D_REG;
+ $$.reg = $1;
+ }
+| LSP
+ {
+ $$ = nullgen;
+ $$.type = D_SP;
+ $$.reg = REGSP;
+ }
+
+shift:
+ sreg '<' '<' scon
+ {
+ $$ = nullgen;
+ $$.type = D_SHIFT;
+ $$.offset = ($1 << 16) | ($4 << 10) | (0 << 22);
+ }
+| sreg '>' '>' scon
+ {
+ $$ = nullgen;
+ $$.type = D_SHIFT;
+ $$.offset = (($1&0x1F) << 16) | ($4 << 10) | (1 << 22);
+ }
+| sreg '-' '>' scon
+ {
+ $$ = nullgen;
+ $$.type = D_SHIFT;
+ $$.offset = ($1 << 16) | ($4 << 10) | (2 << 22);
+ }
+| sreg LAT '>' scon
+ {
+ $$ = nullgen;
+ $$.type = D_SHIFT;
+ $$.offset = ($1 << 16) | ($4 << 10) | (3 << 22);
+ }
+
+extreg:
+ sreg
+ {
+ $$ = nullgen;
+ $$.type = D_REG;
+ $$.reg = $1;
+ }
+| sreg LEXT
+ {
+ $$ = nullgen;
+ $$.type = D_EXTREG;
+ $$.reg = $1;
+ $$.offset = ($1 << 16) | ($2 << 13);
+ }
+| sreg LEXT '<' '<' con
+ {
+ if($5 < 0 || $5 > 4)
+ yyerror("shift value out of range");
+ $$ = nullgen;
+ $$.type = D_EXTREG;
+ $$.reg = $1;
+ $$.offset = ($1 << 16) | ($2 << 13) | ($5 << 10);
+ }
+
+indexreg:
+ sreg
+ {
+ $$ = (3 << 8) | $1;
+ }
+| sreg LEXT
+ {
+ $$ = ($2 << 8) | $1;
+ }
+
+scon:
+ con
+ {
+ if($$ < 0 || $$ >= 64)
+ yyerror("shift value out of range");
+ $$ = $1&0x3F;
+ }
+
+sreg:
+ LREG
+| LR '(' expr ')'
+ {
+ if($3 < 0 || $3 >= NREG)
+ print("register value out of range\n");
+ $$ = $3;
+ }
+
+spreg:
+ sreg
+| LSP
+ {
+ $$ = REGSP;
+ }
+
+spr:
+ LSPREG
+ {
+ $$ = nullgen;
+ $$.type = D_SPR;
+ $$.offset = $1;
+ }
+| LSPR '(' con ')'
+ {
+ $$ = nullgen;
+ $$.type = $1;
+ $$.offset = $3;
+ }
+
+frcon:
+ freg
+| fcon
+
+freg:
+ LFREG
+ {
+ $$ = nullgen;
+ $$.type = D_FREG;
+ $$.reg = $1;
+ }
+| LF '(' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_FREG;
+ $$.reg = $3;
+ }
+
+vgen:
+ oreg
+| vreg
+| vlane
+| vset
+ {
+ $$ = nullgen;
+ $$.type = D_VSET;
+ $$.offset = $1;
+ }
+
+vlane:
+ vreg '[' con ']'
+ {
+ $$.type = D_VLANE;
+ $$.offset = $3;
+ }
+| vset '[' con ']'
+ {
+ $$.type = D_VLANE;
+ $$.offset = $3;
+ }
+
+vset:
+ '{' vreglist '}'
+ {
+ $$ = $2;
+ }
+
+vreglist:
+ vreg
+ {
+ $$ = 1 << $1.reg;
+ }
+| vreg '-' vreg
+ {
+ int i;
+ $$=0;
+ for(i=$1.reg; i<=$3.reg; i++)
+ $$ |= 1<<i;
+ for(i=$3.reg; i<=$1.reg; i++)
+ $$ |= 1<<i;
+ }
+| vreg comma vreglist
+ {
+ $$ = (1<<$1.reg) | $3;
+ }
+
+vreg:
+ LVREG
+ {
+ $$ = nullgen;
+ $$.type = D_VREG;
+ $$.reg = $1;
+ /* TO DO: slice */
+ }
+| LV '(' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_VREG;
+ $$.reg = $3;
+ }
+
+name:
+ con '(' pointer ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.name = $3;
+ $$.sym = S;
+ $$.offset = $1;
+ }
+| LNAME offset '(' pointer ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.name = $4;
+ $$.sym = $1;
+ $$.offset = $2;
+ }
+| LNAME '<' '>' offset '(' LSB ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.name = D_STATIC;
+ $$.sym = $1;
+ $$.offset = $4;
+ }
+
+offset:
+ {
+ $$ = 0;
+ }
+| '+' con
+ {
+ $$ = $2;
+ }
+| '-' con
+ {
+ $$ = -$2;
+ }
+
+pointer:
+ LSB
+| LSP
+| LFP
+
+con:
+ LCONST
+| LVAR
+ {
+ $$ = $1->value;
+ }
+| '-' con
+ {
+ $$ = -$2;
+ }
+| '+' con
+ {
+ $$ = $2;
+ }
+| '~' con
+ {
+ $$ = ~$2;
+ }
+| '(' expr ')'
+ {
+ $$ = $2;
+ }
+
+expr:
+ con
+| expr '+' expr
+ {
+ $$ = $1 + $3;
+ }
+| expr '-' expr
+ {
+ $$ = $1 - $3;
+ }
+| expr '*' expr
+ {
+ $$ = $1 * $3;
+ }
+| expr '/' expr
+ {
+ $$ = $1 / $3;
+ }
+| expr '%' expr
+ {
+ $$ = $1 % $3;
+ }
+| expr '<' '<' expr
+ {
+ $$ = $1 << $4;
+ }
+| expr '>' '>' expr
+ {
+ $$ = $1 >> $4;
+ }
+| expr '&' expr
+ {
+ $$ = $1 & $3;
+ }
+| expr '^' expr
+ {
+ $$ = $1 ^ $3;
+ }
+| expr '|' expr
+ {
+ $$ = $1 | $3;
+ }
diff --git a/sys/src/cmd/7a/lex.c b/sys/src/cmd/7a/lex.c
new file mode 100644
index 000000000..0f8fd5f00
--- /dev/null
+++ b/sys/src/cmd/7a/lex.c
@@ -0,0 +1,1041 @@
+#define EXTERN
+#include "a.h"
+#include "y.tab.h"
+#include <ctype.h>
+
+void
+main(int argc, char *argv[])
+{
+ char *p;
+ int nout, nproc, status, i, c;
+
+ thechar = '7';
+ thestring = "arm64";
+ memset(debug, 0, sizeof(debug));
+ cinit();
+ outfile = 0;
+ include[ninclude++] = ".";
+ 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)
+ Dlist[nDlist++] = p;
+ break;
+
+ case 'I':
+ p = ARGF();
+ setinclude(p);
+ break;
+ } ARGEND
+ if(*argv == 0) {
+ print("usage: %ca [-options] file.s\n", thechar);
+ errorexit();
+ }
+ if(argc > 1 && systemtype(Windows)){
+ print("can't assemble multiple files on windows\n");
+ errorexit();
+ }
+ if(argc > 1 && !systemtype(Windows)) {
+ nproc = 1;
+ if(p = getenv("NPROC"))
+ nproc = atol(p); /* */
+ c = 0;
+ nout = 0;
+ for(;;) {
+ while(nout < nproc && argc > 0) {
+ i = myfork();
+ if(i < 0) {
+ i = mywait(&status);
+ if(i < 0)
+ errorexit();
+ if(status)
+ c++;
+ nout--;
+ continue;
+ }
+ if(i == 0) {
+ print("%s:\n", *argv);
+ if(assemble(*argv))
+ errorexit();
+ exits(0);
+ }
+ nout++;
+ argc--;
+ argv++;
+ }
+ i = mywait(&status);
+ if(i < 0) {
+ if(c)
+ errorexit();
+ exits(0);
+ }
+ if(status)
+ c++;
+ nout--;
+ }
+ }
+ if(assemble(argv[0]))
+ errorexit();
+ exits(0);
+}
+
+int
+assemble(char *file)
+{
+ char ofile[100], incfile[20], *p;
+ int i, of;
+
+ strcpy(ofile, file);
+ p = utfrrune(ofile, pathchar());
+ if(p) {
+ include[0] = ofile;
+ *p++ = 0;
+ } else
+ p = ofile;
+ if(outfile == 0) {
+ outfile = p;
+ if(outfile){
+ p = utfrrune(outfile, '.');
+ if(p)
+ if(p[1] == 's' && p[2] == 0)
+ p[0] = 0;
+ p = utfrune(outfile, 0);
+ p[0] = '.';
+ p[1] = thechar;
+ p[2] = 0;
+ } else
+ outfile = "/dev/null";
+ }
+ p = getenv("INCLUDE");
+ if(p) {
+ setinclude(p);
+ } else {
+ if(systemtype(Plan9)) {
+ sprint(incfile,"/%s/include", thestring);
+ setinclude(strdup(incfile));
+ }
+ }
+
+ of = mycreat(outfile, 0664);
+ if(of < 0) {
+ yyerror("%ca: cannot create %s", thechar, outfile);
+ errorexit();
+ }
+ Binit(&obuf, of, OWRITE);
+
+ pass = 1;
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
+ if(nerrors) {
+ cclean();
+ return nerrors;
+ }
+
+ pass = 2;
+ outhist();
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
+ cclean();
+ return nerrors;
+}
+
+struct
+{
+ char *name;
+ ushort type;
+ ulong value;
+} itab[] =
+{
+ "SP", LSP, D_AUTO,
+ "SB", LSB, D_EXTERN,
+ "FP", LFP, D_PARAM,
+ "PC", LPC, D_BRANCH,
+
+ "R", LR, 0,
+ "R0", LREG, 0,
+ "R1", LREG, 1,
+ "R2", LREG, 2,
+ "R3", LREG, 3,
+ "R4", LREG, 4,
+ "R5", LREG, 5,
+ "R6", LREG, 6,
+ "R7", LREG, 7,
+ "R8", LREG, 8,
+ "R9", LREG, 9,
+ "R10", LREG, 10,
+ "R11", LREG, 11,
+ "R12", LREG, 12,
+ "R13", LREG, 13,
+ "R14", LREG, 14,
+ "R15", LREG, 15,
+ "R16", LREG, 16,
+ "R17", LREG, 17,
+ "R18", LREG, 18,
+ "R19", LREG, 19,
+ "R20", LREG, 20,
+ "R21", LREG, 21,
+ "R22", LREG, 22,
+ "R23", LREG, 23,
+ "R24", LREG, 24,
+ "R25", LREG, 25,
+ "R26", LREG, 26,
+ "R27", LREG, 27,
+ "R28", LREG, 28,
+ "R29", LREG, 29,
+ "R30", LREG, 30,
+ "LR", LREG, 30,
+ "ZR", LREG, 31,
+
+ "RARG", LREG, REGARG,
+ "RARG0", LREG, REGARG,
+ "RSP", LREG, 31,
+
+ "F", LF, 0,
+
+ "F0", LFREG, 0,
+ "F1", LFREG, 1,
+ "F2", LFREG, 2,
+ "F3", LFREG, 3,
+ "F4", LFREG, 4,
+ "F5", LFREG, 5,
+ "F6", LFREG, 6,
+ "F7", LFREG, 7,
+ "F8", LFREG, 8,
+ "F9", LFREG, 9,
+ "F10", LFREG, 10,
+ "F11", LFREG, 11,
+ "F12", LFREG, 12,
+ "F13", LFREG, 13,
+ "F14", LFREG, 14,
+ "F15", LFREG, 15,
+ "F16", LFREG, 16,
+ "F17", LFREG, 17,
+ "F18", LFREG, 18,
+ "F19", LFREG, 19,
+ "F20", LFREG, 20,
+ "F21", LFREG, 21,
+ "F22", LFREG, 22,
+ "F23", LFREG, 23,
+ "F24", LFREG, 24,
+ "F25", LFREG, 25,
+ "F26", LFREG, 26,
+ "F27", LFREG, 27,
+ "F28", LFREG, 28,
+ "F29", LFREG, 29,
+ "F30", LFREG, 30,
+ "F31", LFREG, 31,
+
+ "V", LV, 0,
+
+ "V0", LVREG, 0,
+ "V1", LVREG, 1,
+ "V2", LVREG, 2,
+ "V3", LVREG, 3,
+ "V4", LVREG, 4,
+ "V5", LVREG, 5,
+ "V6", LVREG, 6,
+ "V7", LVREG, 7,
+ "V8", LVREG, 8,
+ "V9", LVREG, 9,
+ "V10", LVREG, 10,
+ "V11", LVREG, 11,
+ "V12", LVREG, 12,
+ "V13", LVREG, 13,
+ "V14", LVREG, 14,
+ "V15", LVREG, 15,
+ "V16", LVREG, 16,
+ "V17", LVREG, 17,
+ "V18", LVREG, 18,
+ "V19", LVREG, 19,
+ "V20", LVREG, 20,
+ "V21", LVREG, 21,
+ "V22", LVREG, 22,
+ "V23", LVREG, 23,
+ "V24", LVREG, 24,
+ "V25", LVREG, 25,
+ "V26", LVREG, 26,
+ "V27", LVREG, 27,
+ "V28", LVREG, 28,
+ "V29", LVREG, 29,
+ "V30", LVREG, 30,
+ "V31", LVREG, 31,
+
+ "FPSR", LFCR, D_FPSR,
+ "FPCR", LFCR, D_FPCR,
+
+ "SPR", LSPR, D_SPR,
+ "NZCV", LSPREG, D_NZCV,
+ "ELR_EL1", LSPREG, D_ELR_EL1,
+ "ELR_EL2", LSPREG, D_ELR_EL2,
+// "ELR_EL3", LSPREG, D_ELR_EL3,
+// "LR_EL0", LSPREG, D_LR_EL0,
+ "DAIF", LSPREG, D_DAIF,
+ "CurrentEL", LSPREG, D_CurrentEL,
+ "SP_EL0", LSPREG, D_SP_EL0,
+// "SP_EL1", LSPREG, D_SP_EL1,
+// "SP_EL2", LSPREG, D_SP_EL2,
+ "SPSel", LSPREG, D_SPSel,
+// "SPSR_abt", LSPREG, D_SPSR_abt,
+ "SPSR_EL1", LSPREG, D_SPSR_EL1,
+ "SPSR_EL2", LSPREG, D_SPSR_EL2,
+// "SPSR_EL3", LSPREG, D_SPSR_EL3,
+// "SPSR_fiq", LSPREG, D_SPSR_fiq,
+// "SPSR_ieq", LSPREG, D_SPSR_ieq,
+// "SPSR_und", LSPREG, D_SPSR_und,
+ "DAIFSet", LSPREG, D_DAIFSet,
+ "DAIFClr", LSPREG, D_DAIFClr,
+
+ "EQ", LCOND, 0,
+ "NE", LCOND, 1,
+ "CS", LCOND, 2,
+ "HS", LCOND, 2,
+ "CC", LCOND, 3,
+ "LO", LCOND, 3,
+ "MI", LCOND, 4,
+ "PL", LCOND, 5,
+ "VS", LCOND, 6,
+ "VC", LCOND, 7,
+ "HI", LCOND, 8,
+ "LS", LCOND, 9,
+ "GE", LCOND, 10,
+ "LT", LCOND, 11,
+ "GT", LCOND, 12,
+ "LE", LCOND, 13,
+ "AL", LCOND, 14,
+
+ ".UXTB", LEXT, 0,
+ ".UXTH", LEXT, 1,
+ ".UXTW", LEXT, 2,
+ ".UXTX", LEXT, 3,
+ ".SXTB", LEXT, 4,
+ ".SXTH", LEXT, 5,
+ ".SXTW", LEXT, 6,
+ ".SXTX", LEXT, 7,
+
+ ".UB", LEXT, 0,
+ ".UH", LEXT, 1,
+ ".UW", LEXT, 2,
+ ".UX", LEXT, 3,
+ ".SB", LEXT, 4,
+ ".SH", LEXT, 5,
+ ".SW", LEXT, 6,
+ ".SX", LEXT, 7,
+
+ "@", LAT, 0,
+
+ "ADC", LTYPE1, AADC,
+ "ADCS", LTYPE1, AADCS,
+ "ADCSW", LTYPE1, AADCSW,
+ "ADCW", LTYPE1, AADCW,
+ "ADD", LTYPE1, AADD,
+ "ADDS", LTYPE1, AADDS,
+ "ADDSW", LTYPE1, AADDSW,
+ "ADDW", LTYPE1, AADDW,
+ "ADR", LTYPEV, AADR,
+ "ADRP", LTYPEV, AADRP,
+ "AND", LTYPE1, AAND,
+ "ANDS", LTYPE1, AANDS,
+ "ANDSW", LTYPE1, AANDSW,
+ "ANDW", LTYPE1, AANDW,
+ "ASR", LTYPE1, AASR,
+ "ASRW", LTYPE1, AASRW,
+ "AT", LTYPEN, AAT,
+ "BFI", LTYPEY, ABFI,
+ "BFIW", LTYPEY, ABFIW,
+ "BFM", LTYPEY, ABFM,
+ "BFMW", LTYPEY, ABFMW,
+ "BFXIL", LTYPEY, ABFXIL,
+ "BFXILW", LTYPEY, ABFXILW,
+ "BIC", LTYPE1, ABIC,
+ "BICS", LTYPE1, ABICS,
+ "BICSW", LTYPE1, ABICSW,
+ "BICW", LTYPE1, ABICW,
+ "BRK", LTYPE6, ABRK,
+ "CBNZ", LTYPE8, ACBNZ,
+ "CBNZW", LTYPE8, ACBNZW,
+ "CBZ", LTYPE8, ACBZ,
+ "CBZW", LTYPE8, ACBZW,
+ "CCMN", LTYPEU, ACCMN,
+ "CCMNW", LTYPEU, ACCMNW,
+ "CCMP", LTYPEU, ACCMP,
+ "CCMPW", LTYPEU, ACCMPW,
+ "CINC", LTYPES, ACINC,
+ "CINCW", LTYPES, ACINCW,
+ "CINV", LTYPES, ACINV,
+ "CINVW", LTYPES, ACINVW,
+ "CLREX", LTYPE6, ACLREX,
+ "CLS", LTYPE2, ACLS,
+ "CLSW", LTYPE2, ACLSW,
+ "CLZ", LTYPE2, ACLZ,
+ "CLZW", LTYPE2, ACLZW,
+ "CMN", LTYPE7, ACMN,
+ "CMNW", LTYPE7, ACMNW,
+ "CMP", LTYPE7, ACMP,
+ "CMPW", LTYPE7, ACMPW,
+ "CNEG", LTYPES, ACNEG,
+ "CNEGW", LTYPES, ACNEGW,
+ "CRC32B", LTYPE1, ACRC32B,
+ "CRC32CB", LTYPE1, ACRC32CB,
+ "CRC32CH", LTYPE1, ACRC32CH,
+ "CRC32CW", LTYPE1, ACRC32CW,
+ "CRC32CX", LTYPE1, ACRC32CX,
+ "CRC32H", LTYPE1, ACRC32H,
+ "CRC32W", LTYPE1, ACRC32W,
+ "CRC32X", LTYPE1, ACRC32X,
+ "CSEL", LTYPES, ACSEL,
+ "CSELW", LTYPES, ACSELW,
+ "CSET", LTYPER, ACSET,
+ "CSETM", LTYPER, ACSETM,
+ "CSETMW", LTYPER, ACSETMW,
+ "CSETW", LTYPER, ACSETW,
+ "CSINC", LTYPES, ACSINC,
+ "CSINCW", LTYPES, ACSINCW,
+ "CSINV", LTYPES, ACSINV,
+ "CSINVW", LTYPES, ACSINVW,
+ "CSNEG", LTYPES, ACSNEG,
+ "CSNEGW", LTYPES, ACSNEGW,
+ "DC", LTYPEN, ADC,
+ "DCPS1", LTYPE6, ADCPS1,
+ "DCPS2", LTYPE6, ADCPS2,
+ "DCPS3", LTYPE6, ADCPS3,
+ "DMB", LDMB, ADMB,
+ "DRPS", LTYPE6, ADRPS,
+ "DSB", LDMB, ADSB,
+ "EON", LTYPE1, AEON,
+ "EONW", LTYPE1, AEONW,
+ "EOR", LTYPE1, AEOR,
+ "EORW", LTYPE1, AEORW,
+ "ERET", LTYPE0, AERET,
+ "EXTR", LTYPEP, AEXTR,
+ "EXTRW", LTYPEP, AEXTRW,
+ "HINT", LDMB, AHINT,
+ "HLT", LTYPE6, AHLT,
+ "HVC", LTYPE6, AHVC,
+ "IC", LTYPEN, AIC,
+ "ISB", LDMB, AISB,
+ "LSL", LTYPE1, ALSL,
+ "LSLW", LTYPE1, ALSLW,
+ "LSR", LTYPE1, ALSR,
+ "LSRW", LTYPE1, ALSRW,
+ "MADD", LTYPEM, AMADD,
+ "MADDW", LTYPEM, AMADDW,
+ "MNEG", LTYPE1, AMNEG,
+ "MNEGW", LTYPE1, AMNEGW,
+ "MRS", LTYPE3, AMRS,
+ "MSR", LTYPE3, AMSR,
+ "MSUB", LTYPEM, AMSUB,
+ "MSUBW", LTYPEM, AMSUBW,
+ "MUL", LTYPE1, AMUL,
+ "MULW", LTYPE1, AMULW,
+ "MVN", LTYPE1, AMVN,
+ "MVNW", LTYPE1, AMVNW,
+ "NEG", LTYPE1, ANEG,
+ "NEGS", LTYPE1, ANEGS,
+ "NEGSW", LTYPE1, ANEGSW,
+ "NEGW", LTYPE1, ANEGW,
+ "NGC", LTYPE2, ANGC,
+ "NGCS", LTYPE2, ANGCS,
+ "NGCSW", LTYPE2, ANGCSW,
+ "NGCW", LTYPE2, ANGCW,
+ "ORN", LTYPE1, AORN,
+ "ORNW", LTYPE1, AORNW,
+ "ORR", LTYPE1, AORR,
+ "ORRW", LTYPE1, AORRW,
+ "PRFM", LTYPE1, APRFM,
+ "PRFUM", LTYPE1, APRFUM,
+ "RBIT", LTYPE2, ARBIT,
+ "RBITW", LTYPE2, ARBITW,
+ "REM", LTYPE1, AREM,
+ "REMW", LTYPE1, AREMW,
+ "RET", LTYPEA, ARET,
+ "REV", LTYPE2, AREV,
+ "REV16", LTYPE2, AREV16,
+ "REV16W", LTYPE2, AREV16W,
+ "REV32", LTYPE2, AREV32,
+ "REVW", LTYPE2, AREVW,
+ "ROR", LTYPE1, AROR,
+ "RORW", LTYPE1, ARORW,
+ "SBC", LTYPE1, ASBC,
+ "SBCS", LTYPE1, ASBCS,
+ "SBCSW", LTYPE1, ASBCSW,
+ "SBCW", LTYPE1, ASBCW,
+ "SBFIZ", LTYPEY, ASBFIZ,
+ "SBFIZW", LTYPEY, ASBFIZW,
+ "SBFM", LTYPEY, ASBFM,
+ "SBFMW", LTYPEY, ASBFMW,
+ "SBFX", LTYPEY, ASBFX,
+ "SBFXW", LTYPEY, ASBFXW,
+ "SDIV", LTYPE1, ASDIV,
+ "SDIVW", LTYPE1, ASDIVW,
+ "SEV", LTYPE0, ASEV,
+ "SEVL", LTYPE0, ASEVL,
+ "SMADDL", LTYPEM, ASMADDL,
+ "SMC", LTYPE6, ASMC,
+ "SMNEGL", LTYPE1, ASMNEGL,
+ "SMSUBL", LTYPEM, ASMSUBL,
+ "SMULH", LTYPE1, ASMULH,
+ "SMULL", LTYPE1, ASMULL,
+ "STLR", LSTXR, ASTLR,
+ "STLRB", LSTXR, ASTLRB,
+ "STLRH", LSTXR, ASTLRH,
+ "STLRW", LSTXR, ASTLRW,
+ "STLXP", LSTXR, ASTLXP,
+ "STLXR", LSTXR, ASTLXR,
+ "STLXRB", LSTXR, ASTLXRB,
+ "STLXRH", LSTXR, ASTLXRH,
+ "STLXRW", LSTXR, ASTLXRW,
+ "STXR", LSTXR, ASTXR,
+ "STXRB", LSTXR, ASTXRB,
+ "STXRH", LSTXR, ASTXRH,
+ "STXP", LSTXR, ASTXP,
+ "STXPW", LSTXR, ASTXPW,
+ "STXRW", LSTXR, ASTXRW,
+ "SUB", LTYPE1, ASUB,
+ "SUBS", LTYPE1, ASUBS,
+ "SUBSW", LTYPE1, ASUBSW,
+ "SUBW", LTYPE1, ASUBW,
+ "SVC", LTYPE6, ASVC,
+ "SXTB", LTYPE2, ASXTB,
+ "SXTBW", LTYPE2, ASXTBW,
+ "SXTH", LTYPE2, ASXTH,
+ "SXTHW", LTYPE2, ASXTHW,
+ "SXTW", LTYPE2, ASXTW,
+ "SYS", LTYPEN, ASYS,
+ "SYSL", LTYPEO, ASYSL,
+ "TBNZ", LTYPET, ATBNZ,
+ "TBZ", LTYPET, ATBZ,
+ "TLBI", LTYPEN, ATLBI,
+ "TST", LTYPE7, ATST,
+ "TSTW", LTYPE7, ATSTW,
+ "UBFIZ", LTYPEY, AUBFIZ,
+ "UBFIZW", LTYPEY, AUBFIZW,
+ "UBFM", LTYPEY, AUBFM,
+ "UBFMW", LTYPEY, AUBFMW,
+ "UBFX", LTYPEY, AUBFX,
+ "UBFXW", LTYPEY, AUBFXW,
+ "UDIV", LTYPE1, AUDIV,
+ "UDIVW", LTYPE1, AUDIVW,
+ "UMADDL", LTYPEM, AUMADDL,
+ "UMNEGL", LTYPE1, AUMNEGL,
+ "UMSUBL", LTYPEM, AUMSUBL,
+ "UMULH", LTYPE1, AUMULH,
+ "UMULL", LTYPE1, AUMULL,
+ "UREM", LTYPE1, AUREM,
+ "UREMW", LTYPE1, AUREMW,
+ "UXTB", LTYPE2, AUXTB,
+ "UXTH", LTYPE2, AUXTH,
+ "UXTBW", LTYPE2, AUXTBW,
+ "UXTHW", LTYPE2, AUXTHW,
+ "UXTW", LTYPE2, AUXTW,
+ "WFE", LTYPE0, AWFE,
+ "WFI", LTYPE0, AWFI,
+ "YIELD", LTYPE0, AYIELD,
+
+ "LDXR", LTYPE3, ALDXR,
+ "LDXRB", LTYPE3, ALDXRB,
+ "LDXRH", LTYPE3, ALDXRH,
+ "LDXRW", LTYPE3, ALDXRW,
+
+ "LDAR", LTYPE3, ALDAR,
+ "LDARB", LTYPE3, ALDARB,
+ "LDARH", LTYPE3, ALDARH,
+ "LDARW", LTYPE3, ALDARW,
+
+ "LDXP", LTYPE3, ALDXP,
+ "LDXPW", LTYPE3, ALDXPW,
+ "LDAXP", LTYPE3, ALDAXP,
+ "LDAXPW", LTYPE3, ALDAXPW,
+
+ "LDAXR", LTYPE3, ALDAXR,
+ "LDAXRB", LTYPE3, ALDAXRB,
+ "LDAXRH", LTYPE3, ALDAXRH,
+ "LDAXRW", LTYPE3, ALDAXRW,
+
+ "MOVK", LMOVK, AMOVK,
+ "MOVKW", LMOVK, AMOVKW,
+ "MOVN", LMOVK, AMOVN,
+ "MOVNW", LMOVK, AMOVNW,
+ "MOVZ", LMOVK, AMOVZ,
+ "MOVZW", LMOVK, AMOVZW,
+
+ "MOVB", LTYPE3, AMOVB,
+ "MOVBU", LTYPE3, AMOVBU,
+ "MOVH", LTYPE3, AMOVH,
+ "MOVHU", LTYPE3, AMOVHU,
+ "MOVW", LTYPE3, AMOVW,
+ "MOVWU", LTYPE3, AMOVWU,
+ "MOV", LTYPE3, AMOV,
+
+ "MOVP", LTYPEJ, AMOVP,
+ "MOVPD", LTYPEJ, AMOVPD,
+ "MOVPQ", LTYPEJ, AMOVPQ,
+ "MOVPS", LTYPEJ, AMOVPS,
+ "MOVPSW", LTYPEJ, AMOVPSW,
+ "MOVPW", LTYPEJ, AMOVPW,
+
+ "MOVNP", LTYPEJ, AMOVNP,
+ "MOVNPW", LTYPEJ, AMOVNPW,
+
+ "FMOVD", LTYPE3, AFMOVD,
+ "FMOVS", LTYPE3, AFMOVS,
+
+ "SCVTFD", LTYPE3, ASCVTFD,
+ "SCVTFS", LTYPE3, ASCVTFS,
+ "SCVTFWD", LTYPE3, ASCVTFWD,
+ "SCVTFWS", LTYPE3, ASCVTFWS,
+ "UCVTFD", LTYPE3, AUCVTFD,
+ "UCVTFS", LTYPE3, AUCVTFS,
+ "UCVTFWD", LTYPE3, AUCVTFWD,
+ "UCVTFWS", LTYPE3, AUCVTFWS,
+
+ "FCVTSD", LTYPE3, AFCVTSD,
+ "FCVTDS", LTYPE3, AFCVTDS,
+ "FCVTZSD", LTYPE3, AFCVTZSD,
+ "FCVTZSDW", LTYPE3, AFCVTZSDW,
+ "FCVTZSS", LTYPE3, AFCVTZSS,
+ "FCVTZSSW", LTYPE3, AFCVTZSSW,
+ "FCVTZUD", LTYPE3, AFCVTZUD,
+ "FCVTZUDW", LTYPE3, AFCVTZUDW,
+ "FCVTZUS", LTYPE3, AFCVTZUS,
+ "FCVTZUSW", LTYPE3, AFCVTZUSW,
+
+ "FCMPS", LTYPEL, AFCMPS,
+ "FCMPD", LTYPEL, AFCMPD,
+ "FCMPES", LTYPEL, AFCMPES,
+ "FCMPED", LTYPEL, AFCMPED,
+ "FCCMPS", LTYPEF, AFCCMPS,
+ "FCCMPD", LTYPEF, AFCCMPD,
+ "FCCMPES", LTYPEF, AFCCMPES,
+ "FCCMPED", LTYPEF, AFCCMPED,
+ "FADDS", LTYPEK, AFADDS,
+ "FADDD", LTYPEK, AFADDD,
+ "FSUBS", LTYPEK, AFSUBS,
+ "FSUBD", LTYPEK, AFSUBD,
+ "FMULS", LTYPEK, AFMULS,
+ "FMULD", LTYPEK, AFMULD,
+ "FDIVS", LTYPEK, AFDIVS,
+ "FDIVD", LTYPEK, AFDIVD,
+
+ "FCSELS", LFCSEL, AFCSELS,
+ "FCSELD", LFCSEL, AFCSELD,
+ "FMAXS", LTYPEK, AFMAXS,
+ "FMINS", LTYPEK, AFMINS,
+ "FMAXD", LTYPEK, AFMAXD,
+ "FMIND", LTYPEK, AFMIND,
+ "FMAXNMS", LTYPEK, AFMAXNMS,
+ "FMAXNMD", LTYPEK, AFMAXNMD,
+ "FMINNMS", LTYPEK, AFMINNMS,
+ "FMINNMD", LTYPEK, AFMINNMD,
+ "FNMULS", LTYPEK, AFNMULS,
+ "FNMULD", LTYPEK, AFNMULD,
+ "FRINTNS", LTYPE3, AFRINTNS,
+ "FRINTND", LTYPE3, AFRINTND,
+ "FRINTPS", LTYPE3, AFRINTPS,
+ "FRINTPD", LTYPE3, AFRINTPD,
+ "FRINTMS", LTYPE3, AFRINTMS,
+ "FRINTMD", LTYPE3, AFRINTMD,
+ "FRINTZS", LTYPE3, AFRINTZS,
+ "FRINTZD", LTYPE3, AFRINTZD,
+ "FRINTAS", LTYPE3, AFRINTAS,
+ "FRINTAD", LTYPE3, AFRINTAD,
+ "FRINTXS", LTYPE3, AFRINTXS,
+ "FRINTXD", LTYPE3, AFRINTXD,
+ "FRINTIS", LTYPE3, AFRINTIS,
+ "FRINTID", LTYPE3, AFRINTID,
+ "FMADDS", LTYPEM, AFMADDS,
+ "FMADDD", LTYPEM, AFMADDD,
+ "FMSUBS", LTYPEM, AFMSUBS,
+ "FMSUBD", LTYPEM, AFMSUBD,
+ "FNMADDS", LTYPEM, AFNMADDS,
+ "FNMADDD", LTYPEM, AFNMADDD,
+ "FNMSUBS", LTYPEM, AFNMSUBS,
+ "FNMSUBD", LTYPEM, AFNMSUBD,
+
+ "FABSS", LTYPE3, AFABSS,
+ "FABSD", LTYPE3, AFABSD,
+ "FNEGS", LTYPE3, AFNEGS,
+ "FNEGD", LTYPE3, AFNEGD,
+ "FSQRTS", LTYPE3, AFSQRTS,
+ "FSQRTD", LTYPE3, AFSQRTD,
+ "FCVTDH", LTYPE3, AFCVTDH,
+ "FCVTHS", LTYPE3, AFCVTHS,
+ "FCVTHD", LTYPE3, AFCVTHD,
+ "FCVTSH", LTYPE3, AFCVTSH,
+
+ "AESD", LTYPEW, AAESD,
+ "AESE", LTYPEW, AAESE,
+ "AESIMC", LTYPEW, AAESIMC,
+ "AESMC", LTYPEW, AAESMC,
+ "SHA1C", LTYPEW, ASHA1C,
+ "SHA1H", LTYPEW, ASHA1H,
+ "SHA1M", LTYPEW, ASHA1M,
+ "SHA1P", LTYPEW, ASHA1P,
+ "SHA1SU0", LTYPEW, ASHA1SU0,
+ "SHA1SU1", LTYPEW, ASHA1SU1,
+ "SHA256H", LTYPEW, ASHA256H,
+ "SHA256H2", LTYPEW, ASHA256H2,
+ "SHA256SU0", LTYPEW, ASHA256SU0,
+ "SHA256SU1", LTYPEW, ASHA256SU1,
+
+ "B", LTYPE4, AB,
+ "BL", LTYPE4, ABL,
+
+ "BEQ", LTYPE5, ABEQ,
+ "BNE", LTYPE5, ABNE,
+ "BCS", LTYPE5, ABCS,
+ "BHS", LTYPE5, ABHS,
+ "BCC", LTYPE5, ABCC,
+ "BLO", LTYPE5, ABLO,
+ "BMI", LTYPE5, ABMI,
+ "BPL", LTYPE5, ABPL,
+ "BVS", LTYPE5, ABVS,
+ "BVC", LTYPE5, ABVC,
+ "BHI", LTYPE5, ABHI,
+ "BLS", LTYPE5, ABLS,
+ "BGE", LTYPE5, ABGE,
+ "BLT", LTYPE5, ABLT,
+ "BGT", LTYPE5, ABGT,
+ "BLE", LTYPE5, ABLE,
+ "BCASE", LTYPE5, ABCASE,
+
+ "TEXT", LTYPEB, ATEXT,
+ "GLOBL", LTYPEB, AGLOBL,
+ "DATA", LTYPEC, ADATA,
+ "CASE", LTYPED, ACASE,
+ "END", LTYPEE, AEND,
+ "WORD", LTYPEH, AWORD,
+ "DWORD", LTYPEH, ADWORD,
+ "NOP", LTYPEQ, ANOP,
+ "RETURN", LTYPEA, ARETURN,
+ 0
+};
+
+void
+cinit(void)
+{
+ Sym *s;
+ int i;
+
+ nullgen.sym = S;
+ nullgen.offset = 0;
+ nullgen.type = D_NONE;
+ nullgen.name = D_NONE;
+ nullgen.reg = NREG;
+ nullgen.xreg = NREG;
+ if(FPCHIP)
+ nullgen.dval = 0;
+ for(i=0; i<sizeof(nullgen.sval); i++)
+ nullgen.sval[i] = 0;
+
+ nerrors = 0;
+ iostack = I;
+ iofree = I;
+ peekc = IGN;
+ nhunk = 0;
+ for(i=0; i<NHASH; i++)
+ hash[i] = S;
+ for(i=0; itab[i].name; i++) {
+ s = slookup(itab[i].name);
+ if(s->value != 0)
+ yyerror("internal: duplicate %s", s->name);
+ 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
+syminit(Sym *s)
+{
+
+ s->type = LNAME;
+ s->value = 0;
+}
+
+void
+cclean(void)
+{
+
+ outcode(AEND, &nullgen, NREG, &nullgen);
+ Bflush(&obuf);
+}
+
+void
+zname(char *n, int t, int s)
+{
+
+ Bputc(&obuf, ANAME);
+ Bputc(&obuf, ANAME>>8);
+ Bputc(&obuf, t); /* type */
+ Bputc(&obuf, s); /* sym */
+ while(*n) {
+ Bputc(&obuf, *n);
+ n++;
+ }
+ Bputc(&obuf, 0);
+}
+
+void
+zaddr(Gen *a, int s)
+{
+ long l;
+ int i;
+ char *n;
+ Ieee e;
+
+ if(a->type == D_CONST){
+ l = a->offset;
+ if((vlong)l != a->offset)
+ a->type = D_DCONST;
+ }
+ Bputc(&obuf, a->type);
+ Bputc(&obuf, a->reg);
+ Bputc(&obuf, s);
+ Bputc(&obuf, a->name);
+ switch(a->type) {
+ default:
+ print("unknown type %d\n", a->type);
+ exits("arg");
+
+ case D_NONE:
+ case D_REG:
+ case D_SP:
+ case D_FREG:
+ case D_VREG:
+ case D_COND:
+ break;
+
+ case D_DCONST:
+ l = a->offset;
+ Bputc(&obuf, l);
+ Bputc(&obuf, l>>8);
+ Bputc(&obuf, l>>16);
+ Bputc(&obuf, l>>24);
+ l = a->offset>>32;
+ Bputc(&obuf, l);
+ Bputc(&obuf, l>>8);
+ Bputc(&obuf, l>>16);
+ Bputc(&obuf, l>>24);
+ break;
+
+ case D_OREG:
+ case D_XPRE:
+ case D_XPOST:
+ case D_CONST:
+ case D_BRANCH:
+ case D_SHIFT:
+ case D_EXTREG:
+ case D_ROFF:
+ case D_SPR:
+ l = a->offset;
+ Bputc(&obuf, l);
+ Bputc(&obuf, l>>8);
+ Bputc(&obuf, l>>16);
+ Bputc(&obuf, l>>24);
+ 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);
+ Bputc(&obuf, e.l);
+ Bputc(&obuf, e.l>>8);
+ Bputc(&obuf, e.l>>16);
+ Bputc(&obuf, e.l>>24);
+ Bputc(&obuf, e.h);
+ Bputc(&obuf, e.h>>8);
+ Bputc(&obuf, e.h>>16);
+ Bputc(&obuf, e.h>>24);
+ break;
+ }
+}
+
+static int
+outsim(Gen *g)
+{
+ Sym *s;
+ int sno, t;
+
+ s = g->sym;
+ if(s == S)
+ return 0;
+ sno = s->sym;
+ if(sno < 0 || sno >= NSYM)
+ sno = 0;
+ t = g->name;
+ if(h[sno].type == t && h[sno].sym == s)
+ return sno;
+ zname(s->name, t, sym);
+ s->sym = sym;
+ h[sym].sym = s;
+ h[sym].type = t;
+ sno = sym;
+ sym++;
+ if(sym >= NSYM)
+ sym = 1;
+ return sno;
+}
+
+void
+outcode(int a, Gen *g1, int reg, Gen *g2)
+{
+ int sf, st;
+
+ if(a != AGLOBL && a != ADATA)
+ pc++;
+ if(pass == 1)
+ return;
+ if(g1->xreg != NREG) {
+ if(reg != NREG || g2->xreg != NREG)
+ yyerror("bad addressing modes");
+ reg = g1->xreg;
+ } else if(g2->xreg != NREG) {
+ if(reg != NREG)
+ yyerror("bad addressing modes");
+ reg = g2->xreg;
+ }
+ do{
+ sf = outsim(g1);
+ st = outsim(g2);
+ } while(sf != 0 && st == sf);
+ Bputc(&obuf, a);
+ Bputc(&obuf, a>>8);
+ Bputc(&obuf, reg);
+ Bputc(&obuf, lineno);
+ Bputc(&obuf, lineno>>8);
+ Bputc(&obuf, lineno>>16);
+ Bputc(&obuf, lineno>>24);
+ zaddr(g1, sf);
+ zaddr(g2, st);
+}
+
+void
+outcode4(int a, Gen *g1, int reg, Gen *g2, Gen *g3)
+{
+ int s1, s2, s3, flag;
+
+ if(a != AGLOBL && a != ADATA)
+ pc++;
+ if(pass == 1)
+ return;
+ do{
+ s1 = outsim(g1);
+ s2 = outsim(g2);
+ s3 = outsim(g3);
+ } while(s1 && (s2 && s1 == s2 || s3 && s1 == s3) || s2 && (s3 && s2 == s3));
+ flag = 0;
+ if(g2->type != D_NONE)
+ flag = 0x40; /* flags extra operand */
+ Bputc(&obuf, a);
+ Bputc(&obuf, a>>8);
+ Bputc(&obuf, reg | flag);
+ Bputc(&obuf, lineno);
+ Bputc(&obuf, lineno>>8);
+ Bputc(&obuf, lineno>>16);
+ Bputc(&obuf, lineno>>24);
+ zaddr(g1, s1);
+ if(flag)
+ zaddr(g2, s2);
+ zaddr(g3, s3);
+}
+
+void
+outhist(void)
+{
+ Gen g;
+ Hist *h;
+ char *p, *q, *op, c;
+ int n;
+
+ g = nullgen;
+ c = pathchar();
+ for(h = hist; h != H; h = h->link) {
+ p = h->name;
+ op = 0;
+ /* on windows skip drive specifier in pathname */
+ if(systemtype(Windows) && p && p[1] == ':'){
+ p += 2;
+ c = *p;
+ }
+ if(p && p[0] != c && h->offset == 0 && pathname){
+ /* on windows skip drive specifier in pathname */
+ if(systemtype(Windows) && pathname[1] == ':') {
+ op = p;
+ p = pathname+2;
+ c = *p;
+ } 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, ANAME>>8);
+ 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, AHISTORY>>8);
+ Bputc(&obuf, 0);
+ Bputc(&obuf, h->line);
+ Bputc(&obuf, h->line>>8);
+ Bputc(&obuf, h->line>>16);
+ Bputc(&obuf, h->line>>24);
+ zaddr(&nullgen, 0);
+ zaddr(&g, 0);
+ }
+}
+
+#include "../cc/lexbody"
+#include "../cc/macbody"
+#include "../cc/compat"
diff --git a/sys/src/cmd/7a/mkfile b/sys/src/cmd/7a/mkfile
new file mode 100644
index 000000000..e48fbea48
--- /dev/null
+++ b/sys/src/cmd/7a/mkfile
@@ -0,0 +1,19 @@
+</$objtype/mkfile
+
+TARG=7a
+OFILES=\
+ y.tab.$O\
+ lex.$O\
+
+HFILES=\
+ ../7c/7.out.h\
+ y.tab.h\
+ a.h\
+
+YFILES=a.y\
+
+BIN=/$objtype/bin
+< /sys/src/cmd/mkone
+YFLAGS=-D1 -d
+
+lex.$O: ../cc/macbody ../cc/lexbody