diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ka |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ka')
-rwxr-xr-x | sys/src/cmd/ka/a.h | 182 | ||||
-rwxr-xr-x | sys/src/cmd/ka/a.y | 734 | ||||
-rwxr-xr-x | sys/src/cmd/ka/l.s | 696 | ||||
-rwxr-xr-x | sys/src/cmd/ka/lex.c | 723 | ||||
-rwxr-xr-x | sys/src/cmd/ka/mkfile | 19 | ||||
-rwxr-xr-x | sys/src/cmd/ka/note | 274 |
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 |