summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ka
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ka
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ka')
-rwxr-xr-xsys/src/cmd/ka/a.h182
-rwxr-xr-xsys/src/cmd/ka/a.y734
-rwxr-xr-xsys/src/cmd/ka/l.s696
-rwxr-xr-xsys/src/cmd/ka/lex.c723
-rwxr-xr-xsys/src/cmd/ka/mkfile19
-rwxr-xr-xsys/src/cmd/ka/note274
6 files changed, 2628 insertions, 0 deletions
diff --git a/sys/src/cmd/ka/a.h b/sys/src/cmd/ka/a.h
new file mode 100755
index 000000000..9ab6ec68d
--- /dev/null
+++ b/sys/src/cmd/ka/a.h
@@ -0,0 +1,182 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "../kc/k.out.h"
+
+#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 500
+#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;
+ long offset;
+ short type;
+ short reg;
+ short xreg;
+ short name;
+ double dval;
+ char sval[8];
+};
+
+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 int nosched;
+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 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 macprag(void);
+void maclin(void);
+void macif(int);
+void macend(void);
+void dodefine(char*);
+void prfile(long);
+void outhist(void);
+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);
+char* mygetwd(char*, int);
+int myexec(char*, char*[]);
+int mydup(int, int);
+int myfork(void);
+int mypipe(int*);
+void* mysbrk(ulong);
diff --git a/sys/src/cmd/ka/a.y b/sys/src/cmd/ka/a.y
new file mode 100755
index 000000000..4d927203b
--- /dev/null
+++ b/sys/src/cmd/ka/a.y
@@ -0,0 +1,734 @@
+%{
+#include "a.h"
+%}
+%union
+{
+ Sym *sym;
+ long lval;
+ double dval;
+ char sval[8];
+ Gen gen;
+}
+%left '|'
+%left '^'
+%left '&'
+%left '<' '>'
+%left '+' '-'
+%left '*' '/' '%'
+%token <lval> LMOVW LMOVD LMOVB LSWAP LADDW LCMP
+%token <lval> LBRA LFMOV LFCONV LFADD LCPOP LTRAP LJMPL LXORW
+%token <lval> LNOP LEND LRETT LUNIMP LTEXT LDATA LRETRN
+%token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH
+%token <lval> LREG LFREG LR LC LF
+%token <lval> LFSR LFPQ LPSR LSCHED
+%token <dval> LFCONST
+%token <sval> LSCONST
+%token <sym> LNAME LLAB LVAR
+%type <lval> con expr pointer offset sreg
+%type <gen> addr rreg name psr creg freg
+%type <gen> imm ximm fimm rel fsr fpq
+%%
+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;
+ }
+| LSCHED ';'
+ {
+ nosched = $1;
+ }
+| ';'
+| inst ';'
+| error ';'
+
+inst:
+/*
+ * B.1 load integer instructions
+ */
+ LMOVW rreg ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVW addr ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD addr ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVB rreg ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVB addr ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.2 load floating instructions
+ * includes CSR
+ */
+| LMOVD addr ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LFMOV addr ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LFMOV fimm ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LFMOV freg ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LFMOV freg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVW addr ',' fsr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.3 load coprocessor instructions
+ * excludes CSR
+ */
+| LMOVW addr ',' creg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD addr ',' creg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.4 store integer instructions
+ */
+| LMOVW rreg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVW imm ',' addr
+ {
+ if($2.offset != 0)
+ yyerror("constant must be zero");
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD rreg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVB rreg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVB imm ',' addr
+ {
+ if($2.offset != 0)
+ yyerror("constant must be zero");
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.5 store floating instructions
+ * includes CSR and CQ
+ */
+| LMOVW freg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD freg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVW fsr ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD fpq ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.6 store coprocessor instructions
+ * excludes CSR and CQ
+ */
+| LMOVW creg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD creg ',' addr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.7 atomic load unsigned byte (TAS)
+ * B.8 swap
+ */
+| LSWAP addr ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.9 add instructions
+ * B.10 tagged add instructions
+ * B.11 subtract instructions
+ * B.12 tagged subtract instructions
+ * B.13 multiply step instruction
+ * B.14 logical instructions
+ * B.15 shift instructions
+ * B.17 save/restore
+ */
+| LADDW rreg ',' sreg ',' rreg
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LADDW imm ',' sreg ',' rreg
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LADDW rreg ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LADDW imm ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LXORW rreg ',' sreg ',' rreg
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LXORW imm ',' sreg ',' rreg
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LXORW rreg ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LXORW imm ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.16 set hi
+ * other pseudo moves
+ */
+| LMOVW imm ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD imm ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVW ximm ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVD ximm ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.18 branch on integer condition
+ * B.19 floating point branch on condition
+ * B.20 coprocessor branch on condition
+ */
+| LBRA comma rel
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+/*
+ * B.21 call instruction
+ * B.22 jump and link instruction
+ */
+| LJMPL comma rel
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+| LJMPL comma addr
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+| LJMPL comma sreg ',' rel
+ {
+ outcode($1, &nullgen, $3, &$5);
+ }
+| LJMPL comma sreg ',' addr
+ {
+ outcode($1, &nullgen, $3, &$5);
+ }
+/*
+ * B.23 return from trap
+ */
+| LRETT rreg ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.28 instruction cache flush
+ */
+| LFLUSH rel comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LFLUSH addr comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+/*
+ * B.24 trap on condition
+ */
+| LTRAP rreg ',' sreg
+ {
+ outcode($1, &$2, $4, &nullgen);
+ }
+| LTRAP imm ',' sreg
+ {
+ outcode($1, &$2, $4, &nullgen);
+ }
+| LTRAP rreg comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LTRAP comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+/*
+ * B.25 read state register instructions
+ */
+| LMOVW psr ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * B.26 write state register instructions BOTCH XOR
+ */
+| LMOVW rreg ',' psr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LMOVW imm ',' psr
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LXORW rreg ',' sreg ',' psr
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LXORW imm ',' sreg ',' psr
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+/*
+ * B.27 unimplemented trap
+ */
+| LUNIMP comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+| LUNIMP imm comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+/*
+ * B.29 floating point operate
+ */
+| LFCONV freg ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LFADD freg ',' freg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LFADD freg ',' freg ',' freg
+ {
+ outcode($1, &$2, $4.reg, &$6);
+ }
+/*
+ * B.30 coprocessor operate
+ */
+| LCPOP creg ',' creg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LCPOP creg ',' creg ',' creg
+ {
+ outcode($1, &$2, $4.reg, &$6);
+ }
+/*
+ * CMP
+ */
+| LCMP rreg ',' rreg
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LCMP rreg ',' imm
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+/*
+ * NOP
+ */
+| LNOP comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+| LNOP rreg comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LNOP freg comma
+ {
+ outcode($1, &$2, NREG, &nullgen);
+ }
+| LNOP ',' rreg
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+| LNOP ',' freg
+ {
+ outcode($1, &nullgen, NREG, &$3);
+ }
+/*
+ * END
+ */
+| LEND comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+/*
+ * TEXT/GLOBL
+ */
+| LTEXT name ',' imm
+ {
+ outcode($1, &$2, NREG, &$4);
+ }
+| LTEXT name ',' con ',' imm
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+/*
+ * DATA
+ */
+| LDATA name '/' con ',' imm
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LDATA name '/' con ',' ximm
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+| LDATA name '/' con ',' fimm
+ {
+ outcode($1, &$2, $4, &$6);
+ }
+/*
+ * RETURN
+ */
+| LRETRN comma
+ {
+ outcode($1, &nullgen, NREG, &nullgen);
+ }
+
+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;
+ }
+
+rreg:
+ sreg
+ {
+ $$ = nullgen;
+ $$.type = D_REG;
+ $$.reg = $1;
+ }
+
+fsr:
+ LFSR
+ {
+ $$ = nullgen;
+ $$.type = D_PREG;
+ $$.reg = $1;
+ }
+
+fpq:
+ LFPQ
+ {
+ $$ = nullgen;
+ $$.type = D_PREG;
+ $$.reg = $1;
+ }
+
+psr:
+ LPSR
+ {
+ $$ = nullgen;
+ $$.type = D_PREG;
+ $$.reg = $1;
+ }
+
+creg:
+ LCREG
+ {
+ $$ = nullgen;
+ $$.type = D_CREG;
+ $$.reg = $1;
+ }
+| LC '(' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_CREG;
+ $$.reg = $3;
+ }
+
+freg:
+ LFREG
+ {
+ $$ = nullgen;
+ $$.type = D_FREG;
+ $$.reg = $1;
+ }
+| LF '(' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_FREG;
+ $$.reg = $3;
+ }
+
+ximm:
+ '$' addr
+ {
+ $$ = $2;
+ $$.type = D_CONST;
+ }
+| '$' LSCONST
+ {
+ $$ = nullgen;
+ $$.type = D_SCONST;
+ memcpy($$.sval, $2, sizeof($$.sval));
+ }
+
+fimm:
+ '$' LFCONST
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = $2;
+ }
+| '$' '-' LFCONST
+ {
+ $$ = nullgen;
+ $$.type = D_FCONST;
+ $$.dval = -$3;
+ }
+
+imm: '$' con
+ {
+ $$ = nullgen;
+ $$.type = D_CONST;
+ $$.offset = $2;
+ }
+
+sreg:
+ LREG
+| LR '(' con ')'
+ {
+ if($$ < 0 || $$ >= NREG)
+ print("register value out of range\n");
+ $$ = $3;
+ }
+
+addr:
+ '(' sreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.reg = $2;
+ $$.offset = 0;
+ }
+| '(' sreg ',' con ')'
+ {
+ $$ = nullgen;
+ $$.type = D_ASI;
+ $$.reg = $2;
+ $$.offset = $4;
+ }
+| '(' sreg '+' sreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.reg = $2;
+ $$.xreg = $4;
+ $$.offset = 0;
+ }
+| name
+| con '(' sreg ')'
+ {
+ $$ = nullgen;
+ $$.type = D_OREG;
+ $$.reg = $3;
+ $$.offset = $1;
+ }
+
+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;
+ }
+
+comma:
+| ','
+
+offset:
+ {
+ $$ = 0;
+ }
+| '+' con
+ {
+ $$ = $2;
+ }
+| '-' con
+ {
+ $$ = -$2;
+ }
+
+pointer:
+ LSB
+| LSP
+| LFP
+
+con:
+ LCONST
+| LVAR
+ {
+ $$ = $1->value;
+ }
+| '-' con
+ {
+ $$ = -$2;
+ }
+| '+' con
+ {
+ $$ = $2;
+ }
+| '~' con
+ {
+ $$ = ~$2;
+ }
+| '(' expr ')'
+ {
+ $$ = $2;
+ }
+
+expr:
+ con
+| expr '+' expr
+ {
+ $$ = $1 + $3;
+ }
+| expr '-' expr
+ {
+ $$ = $1 - $3;
+ }
+| expr '*' expr
+ {
+ $$ = $1 * $3;
+ }
+| expr '/' expr
+ {
+ $$ = $1 / $3;
+ }
+| expr '%' expr
+ {
+ $$ = $1 % $3;
+ }
+| expr '<' '<' expr
+ {
+ $$ = $1 << $4;
+ }
+| expr '>' '>' expr
+ {
+ $$ = $1 >> $4;
+ }
+| expr '&' expr
+ {
+ $$ = $1 & $3;
+ }
+| expr '^' expr
+ {
+ $$ = $1 ^ $3;
+ }
+| expr '|' expr
+ {
+ $$ = $1 | $3;
+ }
diff --git a/sys/src/cmd/ka/l.s b/sys/src/cmd/ka/l.s
new file mode 100755
index 000000000..b982e5532
--- /dev/null
+++ b/sys/src/cmd/ka/l.s
@@ -0,0 +1,696 @@
+/*
+ * Memory and machine-specific definitions. Used in C and assembler.
+ */
+
+/*
+ * Sizes
+ */
+
+#define BI2BY 8 /* bits per byte */
+#define BI2WD 32 /* bits per word */
+#define BY2WD 4 /* bytes per word */
+#define BY2PG 4096 /* bytes per page */
+#define WD2PG (BY2PG/BY2WD) /* words per page */
+#define PGSHIFT 12 /* log(BY2PG) */
+#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
+
+#define MAXMACH 1 /* max # cpus system can run */
+
+/*
+ * Time
+ */
+#define HZ 20 /* clock frequency */
+#define MS2HZ (1000/HZ) /* millisec per clock tick */
+#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
+#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */
+#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */
+
+/*
+ * PSR bits
+ */
+#define PSREC 0x00002000
+#define PSREF 0x00001000
+#define PSRSUPER 0x00000080
+#define PSRPSUPER 0x00000040
+#define PSRET 0x00000020
+#define SPL(n) (n<<8)
+
+/*
+ * Magic registers
+ */
+
+#define MACH 6 /* R6 is m-> */
+#define USER 5 /* R5 is u-> */
+
+/*
+ * Fundamental addresses
+ */
+
+#define USERADDR 0xE0000000
+#define UREGADDR (USERADDR+BY2PG-((32+6)*BY2WD))
+#define BOOTSTACK (KTZERO-0*BY2PG)
+#define TRAPS (KTZERO-2*BY2PG)
+
+/*
+ * MMU
+ */
+
+#define VAMASK 0x3FFFFFFF
+#define NPMEG (1<<12)
+#define BY2SEGM (1<<18)
+#define PG2SEGM (1<<6)
+#define NTLBPID (1+NCONTEXT) /* TLBPID 0 is unallocated */
+#define NCONTEXT 8
+#define CONTEXT 0x30000000 /* in ASI 2 */
+
+/*
+ * MMU regions
+ */
+#define INVALIDSEGM 0xFFFC0000 /* highest seg of VA reserved as invalid */
+#define INVALIDPMEG 0x7F
+#define SCREENSEGM 0xFFF80000
+#define SCREENPMEG 0x7E
+#define ROMSEGM 0xFFE80000
+#define ROMEND 0xFFEA0000
+#define PG2ROM ((ROMEND-ROMSEGM)/BY2PG)
+#define IOSEGM0 ROMSEGM /* see mmuinit() */
+#define NIOSEGM ((SCREENSEGM-ROMSEGM)/BY2SEGM)
+#define IOPMEG0 (SCREENPMEG-NIOSEGM)
+#define IOSEGM ROMEND
+#define IOEND SCREENSEGM
+#define TOPPMEG IOPMEG0
+
+/*
+ * MMU entries
+ */
+#define PTEVALID (1<<31)
+#define PTERONLY (0<<30)
+#define PTEWRITE (1<<30)
+#define PTEKERNEL (1<<29)
+#define PTENOCACHE (1<<28)
+#define PTEMAINMEM (0<<26)
+#define PTEIO (1<<26)
+#define PTEACCESS (1<<25)
+#define PTEMODIFY (1<<24)
+#define PTEUNCACHED 0
+#define PTEMAPMEM (1024*1024)
+#define PTEPERTAB (PTEMAPMEM/BY2PG)
+#define SEGMAPSIZE 16
+
+#define INVALIDPTE 0
+#define PPN(pa) ((pa>>12)&0xFFFF)
+
+/*
+ * Weird addresses in various ASI's
+ */
+#define CACHETAGS 0x80000000 /* ASI 2 */
+#define CACHEDATA 0x90000000 /* ASI 2 */
+#define SER 0x60000000 /* ASI 2 */
+#define SEVAR 0x60000004 /* ASI 2 */
+#define ASER 0x60000008 /* ASI 2 */
+#define ASEVAR 0x6000000C /* ASI 2 */
+#define ENAB 0x40000000 /* ASI 2 */
+#define ENABCACHE 0x10
+#define ENABRESET 0x04
+
+/*
+ * Virtual addresses
+ */
+#define VTAG(va) ((va>>22)&0x03F)
+#define VPN(va) ((va>>13)&0x1FF)
+
+#define PARAM ((char*)0x40500000)
+#define TLBFLUSH_ 0x01
+
+/*
+ * Address spaces
+ */
+
+#define UZERO 0x00000000 /* base of user address space */
+#define UTZERO (UZERO+BY2PG) /* first address in user text */
+#define TSTKTOP 0x10000000 /* end of new stack in sysexec */
+#define TSTKSIZ 32
+#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
+#define KZERO 0xE0000000 /* base of kernel address space */
+#define KTZERO (KZERO+4*BY2PG) /* first address in kernel text */
+#define USTKSIZE (4*1024*1024) /* size of user stack */
+
+#define MACHSIZE 4096
+
+#define isphys(x) (((ulong)(x)&0xF0000000) == KZERO)
+
+#define SYSPSR (SPL(0x0)|PSREF|PSRSUPER|0)
+#define NOOP OR R0, R0; OR R0, R0; OR R0, R0
+
+TEXT start(SB), $-4
+
+ /* get virtual, fast */
+ /* we are executing in segment 0, mapped to pmeg 0. stack is there too */
+ /* get virtual by mapping segment(KZERO) to pmeg 0., and next to 1 */
+ MOVW $KZERO, R7
+ MOVB R0, (R7, 3)
+ MOVW $(KZERO+BY2SEGM), R7
+ MOVW $1, R8
+ MOVB R8, (R7, 3)
+ /* now mapped correctly. jmpl to where we want to be */
+ MOVW $setSB(SB), R2
+ MOVW $startvirt(SB), R7
+ JMPL (R7)
+ MOVW $_mul(SB), R0 /* touch _mul etc.; doesn't need to execute */
+ RETURN /* can't get here */
+
+TEXT startvirt(SB), $-4
+
+ MOVW $BOOTSTACK, R1
+
+ MOVW $(SPL(0xF)|PSREF|PSRSUPER), R7
+ MOVW R7, PSR
+
+ MOVW $(0x35<<22), R7 /* NVM OFM DZM AU */
+ MOVW R7, fsr+0(SB)
+ MOVW fsr+0(SB), FSR
+ FMOVD $0.5, F26 /* 0.5 -> F26 */
+ FSUBD F26, F26, F24 /* 0.0 -> F24 */
+ FADDD F26, F26, F28 /* 1.0 -> F28 */
+ FADDD F28, F28, F30 /* 2.0 -> F30 */
+
+ FMOVD F24, F0
+ FMOVD F24, F2
+ FMOVD F24, F4
+ FMOVD F24, F6
+ FMOVD F24, F8
+ FMOVD F24, F10
+ FMOVD F24, F12
+ FMOVD F24, F14
+ FMOVD F24, F16
+ FMOVD F24, F18
+ FMOVD F24, F20
+ FMOVD F24, F22
+
+ MOVW $mach0(SB), R(MACH)
+/* MOVW $0x8, R7 /**/
+ MOVW R0, WIM
+ JMPL main(SB)
+ MOVW (R0), R0
+ RETURN
+
+TEXT swap1(SB), $0
+
+ TAS (R7), R7 /* LDSTUB, thank you ken */
+ RETURN
+
+TEXT swap1_should_work(SB), $0
+
+ MOVW R7, R8
+ MOVW $1, R7
+ SWAP (R8), R7
+ RETURN
+
+TEXT swap1x(SB), $0
+
+ MOVW PSR, R9
+ MOVW R9, R10
+ AND $~PSRET, R10 /* BUG: book says this is buggy */
+ MOVW R10, PSR
+ NOOP
+ MOVW (R7), R7
+ CMP R7, R0
+ BNE was1
+ MOVW $1, R10
+ MOVW R10, (R8)
+was1:
+ MOVW R9, PSR
+ RETURN
+
+TEXT spllo(SB), $0
+
+ MOVW PSR, R7
+ MOVW R7, R10
+ OR $PSRET, R10
+ MOVW R10, PSR
+ NOOP
+ RETURN
+
+TEXT splhi(SB), $0
+
+ MOVW R15, 4(R(MACH)) /* save PC in m->splpc */
+ MOVW PSR, R7
+ MOVW R7, R10
+ AND $~PSRET, R10 /* BUG: book says this is buggy */
+ MOVW R10, PSR
+ NOOP
+ RETURN
+
+TEXT splx(SB), $0
+
+ MOVW R15, 4(R(MACH)) /* save PC in m->splpc */
+ MOVW R7, PSR /* BUG: book says this is buggy */
+ NOOP
+ RETURN
+
+TEXT spldone(SB), $0
+
+ RETURN
+
+TEXT touser(SB), $0
+ MOVW $(SYSPSR&~PSREF), R8
+ MOVW R8, PSR
+ NOOP
+
+ MOVW R7, R1
+ SAVE R0, R0 /* RETT is implicit RESTORE */
+ MOVW $(UTZERO+32), R7 /* PC; header appears in text */
+ MOVW $(UTZERO+32+4), R8 /* nPC */
+ RETT R7, R8
+
+TEXT rfnote(SB), $0
+
+ MOVW R7, R1 /* 1st arg is &uregpointer */
+ ADD $4, R1 /* point at ureg */
+ JMP restore
+
+TEXT traplink(SB), $-4
+
+ /* R8 to R23 are free to play with */
+ /* R17 contains PC, R18 contains nPC */
+ /* R19 has PSR loaded from vector code */
+
+ ANDCC $PSRPSUPER, R19, R0
+ BE usertrap
+
+kerneltrap:
+ /*
+ * Interrupt or fault from kernel
+ */
+ ANDN $7, R1, R20 /* dbl aligned */
+ MOVW R1, (0-(4*(32+6))+(4*1))(R20) /* save R1=SP */
+ /* really clumsy: store these in Ureg so can be restored below */
+ MOVW R2, (0-(4*(32+6))+(4*2))(R20) /* SB */
+ MOVW R5, (0-(4*(32+6))+(4*5))(R20) /* USER */
+ MOVW R6, (0-(4*(32+6))+(4*6))(R20) /* MACH */
+ SUB $(4*(32+6)), R20, R1
+
+trap1:
+ MOVW Y, R20
+ MOVW R20, (4*(32+0))(R1) /* Y */
+ MOVW TBR, R20
+ MOVW R20, (4*(32+1))(R1) /* TBR */
+ AND $~0x1F, R19 /* force CWP=0 */
+ MOVW R19, (4*(32+2))(R1) /* PSR */
+ MOVW R18, (4*(32+3))(R1) /* nPC */
+ MOVW R17, (4*(32+4))(R1) /* PC */
+ MOVW R0, (4*0)(R1)
+ MOVW R3, (4*3)(R1)
+ MOVW R4, (4*4)(R1)
+ MOVW R7, (4*7)(R1)
+ RESTORE R0, R0
+ /* now our registers R8-R31 are same as before trap */
+ /* save registers two at a time */
+ MOVD R8, (4*8)(R1)
+ MOVD R10, (4*10)(R1)
+ MOVD R12, (4*12)(R1)
+ MOVD R14, (4*14)(R1)
+ MOVD R16, (4*16)(R1)
+ MOVD R18, (4*18)(R1)
+ MOVD R20, (4*20)(R1)
+ MOVD R22, (4*22)(R1)
+ MOVD R24, (4*24)(R1)
+ MOVD R26, (4*26)(R1)
+ MOVD R28, (4*28)(R1)
+ MOVD R30, (4*30)(R1)
+ /* SP and SB and u and m are already set; away we go */
+ MOVW R1, R7 /* pointer to Ureg */
+ SUB $8, R1
+ MOVW $SYSPSR, R8
+ MOVW R8, PSR
+ NOOP
+ JMPL trap(SB)
+
+ ADD $8, R1
+restore:
+ MOVW (4*(32+2))(R1), R8 /* PSR */
+ MOVW R8, PSR
+ NOOP
+
+ MOVD (4*30)(R1), R30
+ MOVD (4*28)(R1), R28
+ MOVD (4*26)(R1), R26
+ MOVD (4*24)(R1), R24
+ MOVD (4*22)(R1), R22
+ MOVD (4*20)(R1), R20
+ MOVD (4*18)(R1), R18
+ MOVD (4*16)(R1), R16
+ MOVD (4*14)(R1), R14
+ MOVD (4*12)(R1), R12
+ MOVD (4*10)(R1), R10
+ MOVD (4*8)(R1), R8
+ SAVE R0, R0
+ MOVD (4*6)(R1), R6
+ MOVD (4*4)(R1), R4
+ MOVD (4*2)(R1), R2
+ MOVW (4*(32+0))(R1), R20 /* Y */
+ MOVW R20, Y
+ MOVW (4*(32+4))(R1), R17 /* PC */
+ MOVW (4*(32+3))(R1), R18 /* nPC */
+ MOVW (4*1)(R1), R1 /* restore R1=SP */
+ RETT R17, R18
+
+usertrap:
+ /*
+ * Interrupt or fault from user
+ */
+ MOVW R1, R8
+ MOVW R2, R9
+ MOVW $setSB(SB), R2
+ MOVW $(USERADDR+BY2PG), R1
+ MOVW R8, (0-(4*(32+6))+(4*1))(R1) /* save R1=SP */
+ MOVW R9, (0-(4*(32+6))+(4*2))(R1) /* save R2=SB */
+ MOVW R5, (0-(4*(32+6))+(4*5))(R1) /* save R5=USER */
+ MOVW R6, (0-(4*(32+6))+(4*6))(R1) /* save R6=MACH */
+ MOVW $USERADDR, R(USER)
+ MOVW $mach0(SB), R(MACH)
+ SUB $(4*(32+6)), R1
+ JMP trap1
+
+TEXT syslink(SB), $-4
+
+ /* R8 to R23 are free to play with */
+ /* R17 contains PC, R18 contains nPC */
+ /* R19 has PSR loaded from vector code */
+ /* assume user did it; syscall checks */
+
+ MOVW R1, R8
+ MOVW R2, R9
+ MOVW $setSB(SB), R2
+ MOVW $(USERADDR+BY2PG), R1
+ MOVW R8, (0-(4*(32+6))+4)(R1) /* save R1=SP */
+ SUB $(4*(32+6)), R1
+ MOVW R9, (4*2)(R1) /* save R2=SB */
+ MOVW R3, (4*3)(R1) /* global register */
+ MOVD R4, (4*4)(R1) /* global register, R5=USER */
+ MOVD R6, (4*6)(R1) /* save R6=MACH, R7=syscall# */
+ MOVW $USERADDR, R(USER)
+ MOVW $mach0(SB), R(MACH)
+ MOVW TBR, R20
+ MOVW R20, (4*(32+1))(R1) /* TBR */
+ AND $~0x1F, R19
+ MOVW R19, (4*(32+2))(R1) /* PSR */
+ MOVW R18, (4*(32+3))(R1) /* nPC */
+ MOVW R17, (4*(32+4))(R1) /* PC */
+ RESTORE R0, R0
+ /* now our registers R8-R31 are same as before trap */
+ MOVW R15, (4*15)(R1)
+ /* SP and SB and u and m are already set; away we go */
+ MOVW R1, R7 /* pointer to Ureg */
+ SUB $8, R1
+ MOVW $SYSPSR, R8
+ MOVW R8, PSR
+ JMPL syscall(SB)
+ /* R7 contains return value from syscall */
+
+ ADD $8, R1
+ MOVW (4*(32+2))(R1), R8 /* PSR */
+ MOVW R8, PSR
+ NOOP
+
+ MOVW (4*15)(R1), R15
+ SAVE R0, R0
+ MOVW (4*6)(R1), R6
+ MOVD (4*4)(R1), R4
+ MOVD (4*2)(R1), R2
+ MOVW (4*(32+4))(R1), R17 /* PC */
+ MOVW (4*(32+3))(R1), R18 /* nPC */
+ MOVW (4*1)(R1), R1 /* restore R1=SP */
+ RETT R17, R18
+
+TEXT puttbr(SB), $0
+
+ MOVW R7, TBR
+ NOOP
+ RETURN
+
+TEXT gettbr(SB), $0
+
+ MOVW TBR, R7
+ RETURN
+
+TEXT r1(SB), $0
+
+ MOVW R1, R7
+ RETURN
+
+TEXT getwim(SB), $0
+
+ MOVW WIM, R7
+ RETURN
+
+TEXT setlabel(SB), $0
+
+ MOVW R1, (R7)
+ MOVW R15, 4(R7)
+ MOVW $0, R7
+ RETURN
+
+TEXT gotolabel(SB), $0
+
+ MOVW (R7), R1
+ MOVW 4(R7), R15
+ MOVW $1, R7
+ RETURN
+
+TEXT putcxsegm(SB), $0
+
+ MOVW R7, R8 /* context */
+ MOVW 4(FP), R9 /* segment addr */
+ MOVW 8(FP), R10 /* segment value */
+ MOVW $0xFFE80118, R7
+ JMPL (R7)
+ RETURN
+
+TEXT getpsr(SB), $0
+
+ MOVW PSR, R7
+ RETURN
+
+TEXT putcxreg(SB), $0
+
+ MOVW $CONTEXT, R8
+ MOVB R7, (R8, 2)
+ RETURN
+
+TEXT putb2(SB), $0
+
+ MOVW 4(FP), R8
+ MOVB R8, (R7, 2)
+ RETURN
+
+TEXT getb2(SB), $0
+
+ MOVB (R7, 2), R7
+ RETURN
+
+TEXT getw2(SB), $0
+
+ MOVW (R7, 2), R7
+ RETURN
+
+TEXT putw2(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 2)
+ RETURN
+
+TEXT putw4(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 4)
+ RETURN
+
+TEXT getw4(SB), $0
+
+ MOVW (R7, 4), R7
+ RETURN
+
+TEXT putwC(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xC)
+ RETURN
+
+TEXT putwD(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xD)
+ RETURN
+
+TEXT putwD16(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ RETURN
+
+TEXT putwE(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xE)
+ RETURN
+
+TEXT putwE16(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ RETURN
+
+TEXT putsegm(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 3)
+ RETURN
+
+/*
+ * in savefpregs and restfpregs, incoming R7 points to doubleword
+ * below where F0 will go; doubleword align in and backfill FSR
+ */
+TEXT savefpregs(SB), $0
+
+ ADD $8, R7
+ ANDN $7, R7 /* now MOVD-aligned */
+ MOVW FSR, -4(R7)
+
+ MOVD F0, (0*4)(R7)
+ MOVD F2, (2*4)(R7)
+ MOVD F4, (4*4)(R7)
+ MOVD F6, (6*4)(R7)
+ MOVD F8, (8*4)(R7)
+ MOVD F10, (10*4)(R7)
+ MOVD F12, (12*4)(R7)
+ MOVD F14, (14*4)(R7)
+ MOVD F16, (16*4)(R7)
+ MOVD F18, (18*4)(R7)
+ MOVD F20, (20*4)(R7)
+ MOVD F22, (22*4)(R7)
+ MOVD F24, (24*4)(R7)
+ MOVD F26, (26*4)(R7)
+ MOVD F28, (28*4)(R7)
+ MOVD F30, (30*4)(R7)
+
+ MOVW PSR, R8
+ ANDN $PSREF, R8
+ MOVW R8, PSR
+ RETURN
+
+TEXT restfpregs(SB), $0
+
+ MOVW PSR, R8
+ OR $PSREF, R8
+ MOVW R8, PSR
+
+ ADD $8, R7
+ ANDN $7, R7 /* now MOVD-aligned */
+ OR R0, R0
+
+ MOVW -4(R7), FSR
+
+ MOVD (0*4)(R7), F0
+ MOVD (2*4)(R7), F2
+ MOVD (4*4)(R7), F4
+ MOVD (6*4)(R7), F6
+ MOVD (8*4)(R7), F8
+ MOVD (10*4)(R7), F10
+ MOVD (12*4)(R7), F12
+ MOVD (14*4)(R7), F14
+ MOVD (16*4)(R7), F16
+ MOVD (18*4)(R7), F18
+ MOVD (20*4)(R7), F20
+ MOVD (22*4)(R7), F22
+ MOVD (24*4)(R7), F24
+ MOVD (26*4)(R7), F26
+ MOVD (28*4)(R7), F28
+ MOVD (30*4)(R7), F30
+
+ ANDN $PSREF, R8
+ MOVW R8, PSR
+ RETURN
+
+TEXT clearfpintr(SB), $0
+
+ MOVW $fpq+BY2WD(SB), R7
+ ANDN $0x7, R7 /* must be D aligned */
+ MOVW $fsr+0(SB), R9
+clrq:
+ MOVD FQ, (R7)
+ MOVW FSR, (R9)
+ MOVW (R9), R8
+ AND $(1<<13), R8 /* queue not empty? */
+ BNE clrq
+ RETURN
+
+TEXT getfsr(SB), $0
+ MOVW $fsr+0(SB), R7
+ MOVW FSR, (R7)
+ MOVW (R7), R7
+ RETURN
+
+GLOBL mach0+0(SB), $MACHSIZE
+GLOBL fpq+0(SB), $(3*BY2WD)
+GLOBL fsr+0(SB), $BY2WD
diff --git a/sys/src/cmd/ka/lex.c b/sys/src/cmd/ka/lex.c
new file mode 100755
index 000000000..aa2a98c37
--- /dev/null
+++ b/sys/src/cmd/ka/lex.c
@@ -0,0 +1,723 @@
+#include <ctype.h>
+#define EXTERN
+#include "a.h"
+#include "y.tab.h"
+
+void
+main(int argc, char *argv[])
+{
+ char *p;
+ int nout, nproc, status, i, c;
+
+ thechar = 'k';
+ thestring = "sparc";
+ 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;
+ ushort value;
+} itab[] =
+{
+ "SP", LSP, D_AUTO,
+ "SB", LSB, D_EXTERN,
+ "FP", LFP, D_PARAM,
+ "PC", LPC, D_BRANCH,
+
+ "FSR", LFSR, D_FSR,
+ "CSR", LFSR, D_CSR,
+
+ "FQ", LFPQ, D_FPQ,
+ "CQ", LFPQ, D_CPQ,
+
+ "Y", LPSR, D_Y,
+ "PSR", LPSR, D_PSR,
+ "WIM", LPSR, D_WIM,
+ "TBR", LPSR, D_TBR,
+
+ "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,
+ "R31", LREG, 31,
+
+ "C", LC, 0,
+ "C0", LCREG, 0,
+ "C1", LCREG, 1,
+ "C2", LCREG, 2,
+ "C3", LCREG, 3,
+ "C4", LCREG, 4,
+ "C5", LCREG, 5,
+ "C6", LCREG, 6,
+ "C7", LCREG, 7,
+ "C8", LCREG, 8,
+ "C9", LCREG, 9,
+ "C10", LCREG, 10,
+ "C11", LCREG, 11,
+ "C12", LCREG, 12,
+ "C13", LCREG, 13,
+ "C14", LCREG, 14,
+ "C15", LCREG, 15,
+ "C16", LCREG, 16,
+ "C17", LCREG, 17,
+ "C18", LCREG, 18,
+ "C19", LCREG, 19,
+ "C20", LCREG, 20,
+ "C21", LCREG, 21,
+ "C22", LCREG, 22,
+ "C23", LCREG, 23,
+ "C24", LCREG, 24,
+ "C25", LCREG, 25,
+ "C26", LCREG, 26,
+ "C27", LCREG, 27,
+ "C28", LCREG, 28,
+ "C29", LCREG, 29,
+ "C30", LCREG, 30,
+ "C31", LCREG, 31,
+
+ "F", LF, 0,
+ "F0", LFREG, 0,
+ "F2", LFREG, 2,
+ "F4", LFREG, 4,
+ "F6", LFREG, 6,
+ "F8", LFREG, 8,
+ "F10", LFREG, 10,
+ "F12", LFREG, 12,
+ "F14", LFREG, 14,
+ "F16", LFREG, 16,
+ "F18", LFREG, 18,
+ "F20", LFREG, 20,
+ "F22", LFREG, 22,
+ "F24", LFREG, 24,
+ "F26", LFREG, 26,
+ "F28", LFREG, 28,
+ "F30", LFREG, 30,
+ "F1", LFREG, 1,
+ "F3", LFREG, 3,
+ "F5", LFREG, 5,
+ "F7", LFREG, 7,
+ "F9", LFREG, 9,
+ "F11", LFREG, 11,
+ "F13", LFREG, 13,
+ "F15", LFREG, 15,
+ "F17", LFREG, 17,
+ "F19", LFREG, 19,
+ "F21", LFREG, 21,
+ "F23", LFREG, 23,
+ "F25", LFREG, 25,
+ "F27", LFREG, 27,
+ "F29", LFREG, 29,
+ "F31", LFREG, 31,
+
+ "ADD", LADDW, AADD,
+ "ADDCC", LADDW, AADDCC,
+ "ADDX", LADDW, AADDX,
+ "ADDXCC", LADDW, AADDXCC,
+ "AND", LADDW, AAND,
+ "ANDCC", LADDW, AANDCC,
+ "ANDN", LADDW, AANDN,
+ "ANDNCC", LADDW, AANDNCC,
+ "BA", LBRA, ABA,
+ "BCC", LBRA, ABCC,
+ "BCS", LBRA, ABCS,
+ "BE", LBRA, ABE,
+ "BG", LBRA, ABG,
+ "BGE", LBRA, ABGE,
+ "BGU", LBRA, ABGU,
+ "BL", LBRA, ABL,
+ "BLE", LBRA, ABLE,
+ "BLEU", LBRA, ABLEU,
+ "BN", LBRA, ABN,
+ "BNE", LBRA, ABNE,
+ "BNEG", LBRA, ABNEG,
+ "BPOS", LBRA, ABPOS,
+ "BVC", LBRA, ABVC,
+ "BVS", LBRA, ABVS,
+ "CB0", LBRA, ACB0,
+ "CB01", LBRA, ACB01,
+ "CB012", LBRA, ACB012,
+ "CB013", LBRA, ACB013,
+ "CB02", LBRA, ACB02,
+ "CB023", LBRA, ACB023,
+ "CB03", LBRA, ACB03,
+ "CB1", LBRA, ACB1,
+ "CB12", LBRA, ACB12,
+ "CB123", LBRA, ACB123,
+ "CB13", LBRA, ACB13,
+ "CB2", LBRA, ACB2,
+ "CB23", LBRA, ACB23,
+ "CB3", LBRA, ACB3,
+ "CBA", LBRA, ACBA,
+ "CBN", LBRA, ACBN,
+ "CMP", LCMP, ACMP,
+ "CPOP1", LCPOP, ACPOP1,
+ "CPOP2", LCPOP, ACPOP2,
+ "DATA", LDATA, ADATA,
+ "DIV", LADDW, ADIV,
+ "DIVL", LADDW, ADIVL,
+ "END", LEND, AEND,
+ "FABSD", LFCONV, AFABSD,
+ "FABSF", LFCONV, AFABSF,
+ "FABSX", LFCONV, AFABSX,
+ "FADDD", LFADD, AFADDD,
+ "FADDF", LFADD, AFADDF,
+ "FADDX", LFADD, AFADDX,
+ "FBA", LBRA, AFBA,
+ "FBE", LBRA, AFBE,
+ "FBG", LBRA, AFBG,
+ "FBGE", LBRA, AFBGE,
+ "FBL", LBRA, AFBL,
+ "FBLE", LBRA, AFBLE,
+ "FBLG", LBRA, AFBLG,
+ "FBN", LBRA, AFBN,
+ "FBNE", LBRA, AFBNE,
+ "FBO", LBRA, AFBO,
+ "FBU", LBRA, AFBU,
+ "FBUE", LBRA, AFBUE,
+ "FBUG", LBRA, AFBUG,
+ "FBUGE", LBRA, AFBUGE,
+ "FBUL", LBRA, AFBUL,
+ "FBULE", LBRA, AFBULE,
+ "FCMPD", LFADD, AFCMPD,
+ "FCMPED", LFADD, AFCMPED,
+ "FCMPEF", LFADD, AFCMPEF,
+ "FCMPEX", LFADD, AFCMPEX,
+ "FCMPF", LFADD, AFCMPF,
+ "FCMPX", LFADD, AFCMPX,
+ "FDIVD", LFADD, AFDIVD,
+ "FDIVF", LFADD, AFDIVF,
+ "FDIVX", LFADD, AFDIVX,
+ "FMOVD", LFMOV, AFMOVD,
+ "FMOVDF", LFCONV, AFMOVDF,
+ "FMOVDW", LFCONV, AFMOVDW,
+ "FMOVDX", LFCONV, AFMOVDX,
+ "FMOVF", LFMOV, AFMOVF,
+ "FMOVFD", LFCONV, AFMOVFD,
+ "FMOVFW", LFCONV, AFMOVFW,
+ "FMOVFX", LFCONV, AFMOVFX,
+ "FMOVWD", LFCONV, AFMOVWD,
+ "FMOVWF", LFCONV, AFMOVWF,
+ "FMOVWX", LFCONV, AFMOVWX,
+ "FMOVX", LFCONV, AFMOVX,
+ "FMOVXD", LFCONV, AFMOVXD,
+ "FMOVXF", LFCONV, AFMOVXF,
+ "FMOVXW", LFCONV, AFMOVXW,
+ "FMULD", LFADD, AFMULD,
+ "FMULF", LFADD, AFMULF,
+ "FMULX", LFADD, AFMULX,
+ "FNEGD", LFCONV, AFNEGD,
+ "FNEGF", LFCONV, AFNEGF,
+ "FNEGX", LFCONV, AFNEGX,
+ "FSQRTD", LFCONV, AFSQRTD,
+ "FSQRTF", LFCONV, AFSQRTF,
+ "FSQRTX", LFCONV, AFSQRTX,
+ "FSUBD", LFADD, AFSUBD,
+ "FSUBF", LFADD, AFSUBF,
+ "FSUBX", LFADD, AFSUBX,
+ "GLOBL", LTEXT, AGLOBL,
+ "IFLUSH", LFLUSH, AIFLUSH,
+ "JMPL", LJMPL, AJMPL,
+ "JMP", LJMPL, AJMP,
+ "MOD", LADDW, AMOD,
+ "MODL", LADDW, AMODL,
+ "MOVB", LMOVB, AMOVB,
+ "MOVBU", LMOVB, AMOVBU,
+ "MOVD", LMOVD, AMOVD,
+ "MOVH", LMOVB, AMOVH,
+ "MOVHU", LMOVB, AMOVHU,
+ "MOVW", LMOVW, AMOVW,
+ "MUL", LADDW, AMUL,
+ "MULSCC", LADDW, AMULSCC,
+ "NOP", LNOP, ANOP,
+ "OR", LADDW, AOR,
+ "ORCC", LADDW, AORCC,
+ "ORN", LADDW, AORN,
+ "ORNCC", LADDW, AORNCC,
+ "RESTORE", LADDW, ARESTORE,
+ "RETT", LRETT, ARETT,
+ "RETURN", LRETRN, ARETURN,
+ "SAVE", LADDW, ASAVE,
+ "SLL", LADDW, ASLL,
+ "SRA", LADDW, ASRA,
+ "SRL", LADDW, ASRL,
+ "SUB", LADDW, ASUB,
+ "SUBCC", LADDW, ASUBCC,
+ "SUBX", LADDW, ASUBX,
+ "SUBXCC", LADDW, ASUBXCC,
+ "SWAP", LSWAP, ASWAP,
+ "TA", LTRAP, ATA,
+ "TADDCC", LADDW, ATADDCC,
+ "TADDCCTV", LADDW, ATADDCCTV,
+ "TAS", LSWAP, ATAS,
+ "TCC", LTRAP, ATCC,
+ "TCS", LTRAP, ATCS,
+ "TE", LTRAP, ATE,
+ "TEXT", LTEXT, ATEXT,
+ "TG", LTRAP, ATG,
+ "TGE", LTRAP, ATGE,
+ "TGU", LTRAP, ATGU,
+ "TL", LTRAP, ATL,
+ "TLE", LTRAP, ATLE,
+ "TLEU", LTRAP, ATLEU,
+ "TN", LTRAP, ATN,
+ "TNE", LTRAP, ATNE,
+ "TNEG", LTRAP, ATNEG,
+ "TPOS", LTRAP, ATPOS,
+ "TSUBCC", LADDW, ATSUBCC,
+ "TSUBCCTV", LADDW, ATSUBCCTV,
+ "TVC", LTRAP, ATVC,
+ "TVS", LTRAP, ATVS,
+ "UNIMP", LUNIMP, AUNIMP,
+ "WORD", LUNIMP, AWORD,
+ "XNOR", LADDW, AXNOR,
+ "XNORCC", LADDW, AXNORCC,
+ "XOR", LXORW, AXOR,
+ "XORCC", LADDW, AXORCC,
+
+ "SCHED", LSCHED, 0,
+ "NOSCHED", LSCHED, 0x80,
+
+ 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);
+ s->type = itab[i].type;
+ s->value = itab[i].value;
+ }
+
+ pathname = allocn(pathname, 0, 100);
+ if(mygetwd(pathname, 99) == 0) {
+ pathname = allocn(pathname, 100, 900);
+ if(mygetwd(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, 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;
+
+ 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_FREG:
+ case D_CREG:
+ case D_PREG:
+ break;
+
+ case D_OREG:
+ case D_ASI:
+ case D_CONST:
+ case D_BRANCH:
+ 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;
+ }
+}
+
+void
+outcode(int a, Gen *g1, int reg, Gen *g2)
+{
+ int sf, st, t;
+ Sym *s;
+
+ if(pass == 1)
+ goto out;
+ 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;
+ }
+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, reg|nosched);
+ Bputc(&obuf, lineno);
+ Bputc(&obuf, lineno>>8);
+ Bputc(&obuf, lineno>>16);
+ Bputc(&obuf, lineno>>24);
+ zaddr(g1, sf);
+ zaddr(g2, st);
+
+out:
+ if(a != AGLOBL && a != ADATA)
+ pc++;
+}
+
+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, 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, 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/ka/mkfile b/sys/src/cmd/ka/mkfile
new file mode 100755
index 000000000..afa5ad506
--- /dev/null
+++ b/sys/src/cmd/ka/mkfile
@@ -0,0 +1,19 @@
+</$objtype/mkfile
+
+TARG=ka
+OFILES=\
+ y.tab.$O\
+ lex.$O\
+
+HFILES=\
+ ../kc/k.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 ../cc/compat
diff --git a/sys/src/cmd/ka/note b/sys/src/cmd/ka/note
new file mode 100755
index 000000000..3ecf7bc7f
--- /dev/null
+++ b/sys/src/cmd/ka/note
@@ -0,0 +1,274 @@
+/* load instructions */
+
+ LDSB MOVB x, R
+ LDSBA MOVB x, R, asi
+ LDSH MOVH x, R
+ LDSHA MOVH x, R, asi
+ LDUB MOVBU x, R
+ LDUBA MOVBU x, R, asi
+ LDUH MOVHU x, R
+ LDUHA MOVHU x, R, asi
+ LD MOVW x, R
+ LDA MOVW x, R, asi
+ LDD MOVD x, R
+ LDDA MOVD x, R, asi
+
+note: x is (R+R) or offset(R)
+note: MOVD is a bad name, means double word
+
+/* load floating */
+
+ LDF MOVF x, FR
+ LDDF MOVD x, FR
+ LDFSR MOVW x, FPSR
+
+note: MOVF maybe is MOVW
+
+/* load coprocessor */
+
+ LDC MOVW x, CR
+ LDDC MOVD x, CR
+ LDCSR MOVW x, CPSR
+
+/* store */
+
+ STB MOVB R, x
+ STBA MOVB R, x, asi
+ STH MOVH R, x
+ STHA MOVH R, x, asi
+ ST MOVW R, x
+ STA MOVW R, x, asi
+ STD MOVD R, x
+ STDA MOVD R, x, asi
+
+/* store floating *
+
+ STF MOVF FR, x
+ STDF MOVD FR, x
+ STFSR MOVW FPSR, x
+ STDFQ MOVD FPQ, x
+
+note: STDFQ gok
+
+/* store coprocessor */
+
+ STC MOVW CR, x
+ STDC MOVD CR, x
+ STCSR MOVW CPSR, x
+ STDCQ MOVD CPQ, x
+
+/* atomic load/store */
+
+ LDSTUB TAS x
+ LDSTUBA TAS x, asi
+
+/* swap */
+
+ SWAP SWAP R, x
+ SWAPA SWAP R, x, asi
+
+/* calc */
+
+ ADD ADDW y,R, R
+ ADDcc ADDWT y,R, R
+ ADDX ADDC y,R, R
+ ADDXcc ADDCT y,R, R
+ TADDcc
+ TADDccTV
+ SUB
+ SUBcc
+ SUBX
+ SUBXcc
+ TSUBcc
+ TSUBccTV
+ MULScc
+ AND
+ ANDcc
+ ANDN
+ ANDNcc
+ OR
+ ORcc
+ ORN
+ ORNcc
+ XOR
+ XORcc
+ XNOR
+ XNORcc
+ SLL
+ SRL
+ SRA
+
+note: y is R or $simm13
+
+/* sethi */
+
+ SETHI MOVW $c, R /* high 22 bits */
+
+/* save/restore (same as add) */
+
+ SAVE SAVE y,R, R
+ RESTORE RESTORE y,R, R
+
+/* branch on cc */
+
+ BA
+ BN
+ BNE
+ BE
+ BG
+ BLE
+ BGE
+ BL
+ BGU
+ BLEU
+ BCC
+ BCS
+ BPOS
+ BNEG
+ BVC
+ BVS
+
+note: annul bit?
+
+/* branch on fcc */
+
+ FBA
+ FBN
+ FBU
+ FBG
+ FBUG
+ FBL
+ FBUL
+ FBLG
+ FBNE
+ FBE
+ FBUE
+ FBGE
+ FBUGE
+ FBLE
+ FBULE
+ FBO
+
+note: annul bit?
+
+/* branch on coprocecssor cc */
+
+ CBA
+ CBN
+ CB3
+ CB2
+ CB23
+ CB1
+ CB13
+ CB12
+ CB123
+ CB0
+ CB03
+ CB02
+ CB023
+ CB01
+ CB013
+ CB012
+
+note: annul bit?
+
+/* call */
+
+ CALL
+ JAL x, R
+
+/* return from trap */
+
+ RETT x
+
+/* trap on integer cc */
+
+ TA
+ TN
+ TNE
+ TE
+ TG
+ TLE
+ TGE
+ TL
+ TGU
+ TLEU
+ TCC
+ TCS
+ TPOS
+ TNEG
+ TVC
+ TVS
+
+/* read state register */
+
+ RDY MOVW Y, R
+ RDPSR MOVW PSR, R
+ RDWIM MOVW WIM, R
+ RDTBR MOVW TBR, R
+
+/* write state register */
+
+ WRY MOVW R, Y
+ WRPSR MOVW R, PSR
+ WRWIM MOVW R, WIM
+ WRTBR MOVW R, TBR
+
+/* unimplemented */
+
+ UNIMP $C22
+
+/* instruction cache flush */
+
+ IFLUSH x
+
+/* floating op */
+
+ FiTOs
+ FiTOd
+ FiTOx
+
+ FsTOi
+ FdTOi
+ FxTOi
+
+ FsTOd
+ FsTOx
+ FdTOs
+ FdTOx
+ FxTOs
+ FxTOd
+
+ FMOVs
+ FNEGs
+ FABSs
+
+ FSQRTs
+ FSQRTd
+ FSQRTx
+
+ FADDs
+ FADDd
+ FADDx
+ FSUBs
+ FSUBd
+ FSUBx
+
+ FMULs
+ FMULd
+ FMULx
+ FDIVs
+ FDIVd
+ FDIVx
+
+ FCMPs
+ FCMPd
+ FCMPx
+ FCMPEs
+ FCMPEd
+ FCMPEx
+
+/* coprocessor op */
+
+ CPop1
+ CPop2