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/va |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/va')
-rwxr-xr-x | sys/src/cmd/va/a.h | 182 | ||||
-rwxr-xr-x | sys/src/cmd/va/a.y | 588 | ||||
-rwxr-xr-x | sys/src/cmd/va/l.s | 703 | ||||
-rwxr-xr-x | sys/src/cmd/va/lex.c | 702 | ||||
-rwxr-xr-x | sys/src/cmd/va/mkfile | 19 |
5 files changed, 2194 insertions, 0 deletions
diff --git a/sys/src/cmd/va/a.h b/sys/src/cmd/va/a.h new file mode 100755 index 000000000..9b1f4da38 --- /dev/null +++ b/sys/src/cmd/va/a.h @@ -0,0 +1,182 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "../vc/v.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 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; + long offset; + short type; + short reg; + 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 nosched; +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); +int isreg(Gen*); +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 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); +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/va/a.y b/sys/src/cmd/va/a.y new file mode 100755 index 000000000..cbc07fd75 --- /dev/null +++ b/sys/src/cmd/va/a.y @@ -0,0 +1,588 @@ +%{ +#include "a.h" +%} +%union +{ + Sym *sym; + long lval; + double dval; + char sval[8]; + Gen gen; +} +%left '|' +%left '^' +%left '&' +%left '<' '>' +%left '+' '-' +%left '*' '/' '%' +%token <lval> 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> LCONST LSP LSB LFP LPC LHI LLO LMREG +%token <lval> LTYPEX LREG LFREG LFCREG LR LM LF +%token <lval> LFCR LSCHED +%token <dval> LFCONST +%token <sval> LSCONST +%token <sym> LNAME LLAB LVAR +%type <lval> con expr pointer offset sreg +%type <gen> gen vgen lgen vlgen rel reg freg mreg fcreg +%type <gen> imm ximm ireg name oreg imr nireg fgen +%% +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: +/* + * Immed-type + */ + LTYPE1 imr ',' sreg ',' reg + { + outcode($1, &$2, $4, &$6); + } +| LTYPE1 imr ',' reg + { + outcode($1, &$2, NREG, &$4); + } +/* + * NOR + */ +| LTYPE2 imr ',' sreg ',' imr + { + outcode($1, &$2, $4, &$6); + } +| LTYPE2 imr ',' imr + { + outcode($1, &$2, NREG, &$4); + } +/* + * LOAD/STORE, but not MOVW + */ +| LTYPE3 lgen ',' gen + { + if(!isreg(&$2) && !isreg(&$4)) + print("one side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * SPECIAL + */ +| LTYPE4 comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +/* + * MOVW + */ +| LTYPE5 vlgen ',' vgen + { + if(!isreg(&$2) && !isreg(&$4)) + print("one side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * MUL/DIV + */ +| LTYPE6 reg ',' sreg comma + { + outcode($1, &$2, $4, &nullgen); + } +| LTYPE6 reg ',' sreg ',' reg + { + outcode($1, &$2, $4, &$6); + } +/* + * JMP/JAL + */ +| LTYPE7 comma rel + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPE7 comma nireg + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPE8 comma rel + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPE8 comma nireg + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPE8 sreg ',' nireg + { + outcode($1, &nullgen, $2, &$4); + } +/* + * BEQ/BNE + */ +| LTYPE9 gen ',' rel + { + if(!isreg(&$2)) + print("left side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +| LTYPE9 gen ',' sreg ',' rel + { + if(!isreg(&$2)) + print("left side must be register\n"); + outcode($1, &$2, $4, &$6); + } +/* + * B-other + */ +| LTYPEA gen ',' rel + { + if(!isreg(&$2)) + print("left side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * 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); + } +/* + * floating-type + */ +| LTYPED freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LTYPEE freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LTYPEE freg ',' LFREG ',' freg + { + outcode($1, &$2, $4, &$6); + } +| LTYPEF freg ',' LFREG comma + { + outcode($1, &$2, $4, &nullgen); + } +/* + * coprocessor branch + */ +| LTYPEG comma rel + { + outcode($1, &nullgen, NREG, &$3); + } +/* + * word + */ +| LTYPEH comma ximm + { + outcode($1, &nullgen, NREG, &$3); + } +/* + * NOP + */ +| LTYPEI comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +| LTYPEI ',' vgen + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPEI vgen comma + { + outcode($1, &$2, NREG, &nullgen); + } +/* + * BREAK -- overloaded with CACHE opcode + */ +| LTYPEJ comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +| LTYPEJ vgen ',' vgen + { + outcode($1, &$2, NREG, &$4); + } + +comma: +| ',' + +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; + } + +vlgen: + lgen +| fgen +| mreg +| fcreg +| LHI + { + $$ = nullgen; + $$.type = D_HI; + } +| LLO + { + $$ = nullgen; + $$.type = D_LO; + } + +vgen: + gen +| fgen +| mreg +| fcreg +| LHI + { + $$ = nullgen; + $$.type = D_HI; + } +| LLO + { + $$ = nullgen; + $$.type = D_LO; + } + +lgen: + gen +| ximm + +fgen: + freg + +mreg: + LMREG + { + $$ = nullgen; + $$.type = D_MREG; + $$.reg = $1; + } +| LM '(' con ')' + { + $$ = nullgen; + $$.type = D_MREG; + $$.reg = $3; + } + +fcreg: + LFCREG + { + $$ = nullgen; + $$.type = D_FCREG; + $$.reg = $1; + } +| LFCR '(' con ')' + { + $$ = nullgen; + $$.type = D_FCREG; + $$.reg = $3; + } + +freg: + LFREG + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $1; + } +| LF '(' con ')' + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $3; + } + +ximm: '$' con + { + $$ = nullgen; + $$.type = D_CONST; + $$.offset = $2; + } +| '$' oreg + { + $$ = $2; + $$.type = D_CONST; + } +| '$' '*' '$' oreg + { + $$ = $4; + $$.type = D_OCONST; + } +| '$' LSCONST + { + $$ = nullgen; + $$.type = D_SCONST; + memcpy($$.sval, $2, sizeof($$.sval)); + } +| '$' LFCONST + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = $2; + } +| '$' '-' LFCONST + { + $$ = nullgen; + $$.type = D_FCONST; + $$.dval = -$3; + } + +nireg: + ireg +| con ireg + { + if($1 != 0) + yyerror("offset must be zero"); + $$ = $2; + } +| name + { + $$ = $1; + if($1.name != D_EXTERN && $1.name != D_STATIC) { + } + } + +ireg: + '(' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $2; + $$.offset = 0; + } + +gen: + reg +| con + { + $$ = nullgen; + $$.type = D_OREG; + $$.offset = $1; + } +| oreg + +oreg: + name +| name '(' sreg ')' + { + $$ = $1; + $$.type = D_OREG; + $$.reg = $3; + } +| '(' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $2; + $$.offset = 0; + } +| con '(' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $3; + $$.offset = $1; + } + +imr: + reg +| imm + +imm: '$' con + { + $$ = nullgen; + $$.type = D_CONST; + $$.offset = $2; + } + +reg: + sreg + { + $$ = nullgen; + $$.type = D_REG; + $$.reg = $1; + } + +sreg: + LREG +| LR '(' con ')' + { + if($$ < 0 || $$ >= NREG) + print("register value out of range\n"); + $$ = $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/va/l.s b/sys/src/cmd/va/l.s new file mode 100755 index 000000000..2f8e6341f --- /dev/null +++ b/sys/src/cmd/va/l.s @@ -0,0 +1,703 @@ +/* + * 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 MAXMACH 4 /* max # cpus system can run */ + +/* + * Time + */ +#define MS2HZ 50 /* millisec per clock tick */ +#define TK2SEC(t) ((t)/20) /* ticks to seconds */ +#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ +#define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */ + +/* + * CP0 registers + */ + +#define INDEX 0 +#define RANDOM 1 +#define TLBPHYS 2 +#define CONTEXT 4 +#define BADVADDR 8 +#define TLBVIRT 10 +#define STATUS 12 +#define CAUSE 13 +#define EPC 14 +#define PRID 15 + +/* + * M(STATUS) bits + */ +#define IEC 0x00000001 +#define KUC 0x00000002 +#define IEP 0x00000004 +#define KUP 0x00000008 +#define INTMASK 0x0000ff00 +#define SW0 0x00000100 +#define SW1 0x00000200 +#define INTR0 0x00000400 +#define INTR1 0x00000800 +#define INTR2 0x00001000 +#define INTR3 0x00002000 +#define INTR4 0x00004000 +#define INTR5 0x00008000 +#define ISC 0x00010000 +#define SWC 0x00020000 +#define CU1 0x20000000 + +/* + * Traps + */ + +#define UTLBMISS (KSEG0+0x00) +#define EXCEPTION (KSEG0+0x80) + +/* + * Magic registers + */ + +#define MACH 25 /* R25 is m-> */ +#define USER 24 /* R24 is u-> */ +#define MPID 0xBF000000 /* long; low 3 bits identify mp bus slot */ +#define WBFLUSH 0xBC000000 /* D-CACHE data; used for write buffer flush */ + +/* + * Fundamental addresses + */ + +#define MACHADDR 0x80014000 +#define USERADDR 0xC0000000 +#define UREGADDR (USERADDR+BY2PG-4-0xA0) +/* + * MMU + */ + +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xA0000000 +#define KSEG2 0xC0000000 +#define KSEGM 0xE0000000 /* mask to check which seg */ + +#define PTEGLOBL (1<<8) +#define PTEVALID (1<<9) +#define PTEWRITE (1<<10) +#define PTEPID(n) ((n)<<6) + +#define NTLBPID 64 /* number of pids */ +#define NTLB 64 /* number of entries */ +#define TLBROFF 8 /* offset of first randomly indexed entry */ + +/* + * Address spaces + */ + +#define UZERO KUSEG /* base of user address space */ +#define UTZERO (UZERO+BY2PG) /* first address in user text */ +#define USTKTOP KZERO /* byte just beyond user stack */ +#define TSTKTOP (USERADDR+100*BY2PG) /* top of temporary stack */ +#define KZERO KSEG0 /* base of kernel address space */ +#define KTZERO (KSEG0+0x20000) /* first address in kernel text */ +#define USTACKSIZE (4*1024*1024) /* size of user stack */ +/* + * Exception codes + */ +#define CINT 0 /* external interrupt */ +#define CTLBM 1 /* TLB modification */ +#define CTLBL 2 /* TLB miss (load or fetch) */ +#define CTLBS 3 /* TLB miss (store) */ +#define CADREL 4 /* address error (load or fetch) */ +#define CADRES 5 /* address error (store) */ +#define CBUSI 6 /* bus error (fetch) */ +#define CBUSD 7 /* bus error (data load or store) */ +#define CSYS 8 /* system call */ +#define CBRK 9 /* breakpoint */ +#define CRES 10 /* reserved instruction */ +#define CCPU 11 /* coprocessor unusable */ +#define COVF 12 /* arithmetic overflow */ +#define CUNK13 13 /* undefined 13 */ +#define CUNK14 14 /* undefined 14 */ +#define CUNK15 15 /* undefined 15 */ + +#define NSEG 5 + +#define SP R29 + +#define PROM (KSEG1+0x1FC00000) +#define NOOP NOR R0,R0 +#define WAIT NOOP; NOOP + +/* + * Boot first processor + * - why is the processor number loaded from R0 ????? + */ +TEXT start(SB), $-4 + + MOVW $setR30(SB), R30 + MOVW $(CU1|INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1 + MOVW R1, M(STATUS) + WAIT + + MOVW $(0x1C<<7), R1 + MOVW R1, FCR31 /* permit only inexact and underflow */ + NOOP + MOVD $0.5, F26 + SUBD F26, F26, F24 + ADDD F26, F26, F28 + ADDD F28, F28, F30 + + MOVD F24, F0 + MOVD F24, F2 + MOVD F24, F4 + MOVD F24, F6 + MOVD F24, F8 + MOVD F24, F10 + MOVD F24, F12 + MOVD F24, F14 + MOVD F24, F16 + MOVD F24, F18 + MOVD F24, F20 + MOVD F24, F22 + + MOVW $MACHADDR, R(MACH) + ADDU $(BY2PG-4), R(MACH), SP + MOVW $0, R(USER) + MOVW R0, 0(R(MACH)) + + MOVW $edata(SB), R1 + MOVW $end(SB), R2 + +clrbss: + MOVB $0, (R1) + ADDU $1, R1 + BNE R1, R2, clrbss + + MOVW R4, _argc(SB) + MOVW R5, _argv(SB) + MOVW R6, _env(SB) + JAL main(SB) + JMP (R0) + +/* + * Take first processor into user mode + * - argument is stack pointer to user + */ + +TEXT touser(SB), $-4 + + MOVW M(STATUS), R1 + OR $(KUP|IEP), R1 + MOVW R1, M(STATUS) + NOOP + MOVW 0(FP), SP + MOVW $(UTZERO+32), R26 /* header appears in text */ + RFE (R26) + +/* + * Bring subsequent processors on line + */ +TEXT newstart(SB), $0 + + MOVW $setR30(SB), R30 + MOVW $(INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1 + MOVW R1, M(STATUS) + NOOP + MOVW $MACHADDR, R(MACH) + MOVB (MPID+3), R1 + AND $7, R1 + SLL $PGSHIFT, R1, R2 + ADDU R2, R(MACH) + ADDU $(BY2PG-4), R(MACH), SP + MOVW $0, R(USER) + MOVW R1, 0(R(MACH)) + JAL online(SB) + JMP (R0) + +TEXT firmware(SB), $0 + + MOVW $(PROM+0x18), R1 /**/ +/* MOVW $(PROM+0x00), R1 /**/ + JMP (R1) + +TEXT splhi(SB), $0 + + MOVW M(STATUS), R1 + AND $~IEC, R1, R2 + MOVW R2, M(STATUS) + NOOP + RET + +TEXT spllo(SB), $0 + + MOVW M(STATUS), R1 + OR $IEC, R1, R2 + MOVW R2, M(STATUS) + NOOP + RET + +TEXT splx(SB), $0 + + MOVW 0(FP), R1 + MOVW M(STATUS), R2 + AND $IEC, R1 + AND $~IEC, R2 + OR R2, R1 + MOVW R1, M(STATUS) + NOOP + RET + +TEXT wbflush(SB), $-4 + + MOVW $WBFLUSH, R1 + MOVW 0(R1), R1 + RET + +TEXT setlabel(SB), $0 + + MOVW 0(FP), R2 + MOVW $0, R1 + MOVW R31, 0(R2) + MOVW R29, 4(R2) + RET + +TEXT gotolabel(SB), $0 + + MOVW 0(FP), R2 + MOVW $1, R1 + MOVW 0(R2), R31 + MOVW 4(R2), R29 + RET + +TEXT gotopc(SB), $8 + + MOVW 0(FP), R7 /* save arguments for later */ + MOVW _argc(SB), R4 + MOVW _argv(SB), R5 + MOVW _env(SB), R6 + MOVW R0, 4(SP) + MOVW $(64*1024), R1 + MOVW R1, 8(SP) + JAL icflush(SB) + JMP (R7) + +TEXT puttlb(SB), $4 + + JAL splhi(SB) + MOVW 0(FP), R2 + MOVW 4(FP), R3 + MOVW R1, 4(SP) + MOVW R2, M(TLBVIRT) + MOVW R3, M(TLBPHYS) + NOOP + TLBP + NOOP + MOVW M(INDEX), R4 + BGEZ R4, index + TLBWR + NOOP + JAL splx(SB) + RET +index: + TLBWI + NOOP + JAL splx(SB) + RET + +TEXT puttlbx(SB), $0 + + MOVW 0(FP), R4 + MOVW 4(FP), R2 + MOVW 8(FP), R3 + SLL $8, R4 + MOVW R2, M(TLBVIRT) + MOVW R3, M(TLBPHYS) + MOVW R4, M(INDEX) + NOOP + TLBWI + NOOP + RET + +TEXT tlbp(SB), $0 + TLBP + NOOP + MOVW M(INDEX), R1 + RET + +TEXT tlbvirt(SB), $0 + TLBP + NOOP + MOVW M(TLBVIRT), R1 + RET + + +TEXT gettlb(SB), $0 + + MOVW 0(FP), R3 + MOVW 4(FP), R4 + SLL $8, R3 + MOVW R3, M(INDEX) + NOOP + TLBR + NOOP + MOVW M(TLBVIRT), R1 + MOVW M(TLBPHYS), R2 + NOOP + MOVW R1, 0(R4) + MOVW R2, 4(R4) + RET + +TEXT gettlbvirt(SB), $0 + + MOVW 0(FP), R3 + SLL $8, R3 + MOVW R3, M(INDEX) + NOOP + TLBR + NOOP + MOVW M(TLBVIRT), R1 + NOOP + RET + +TEXT vector80(SB), $-4 + + MOVW $exception(SB), R26 + JMP (R26) + +TEXT exception(SB), $-4 + + MOVW M(STATUS), R26 + AND $KUP, R26 + BEQ R26, waskernel + +wasuser: + MOVW SP, R26 + /* + * set kernel sp: ureg - ureg* - pc + * done in 2 steps because R30 is not set + * and the loader will make a literal + */ + MOVW $((UREGADDR-2*BY2WD) & 0xffff0000), SP + OR $((UREGADDR-2*BY2WD) & 0xffff), SP + MOVW R26, 0x10(SP) /* user SP */ + MOVW R31, 0x28(SP) + MOVW R30, 0x2C(SP) + MOVW M(CAUSE), R26 + MOVW R(MACH), 0x3C(SP) + MOVW R(USER), 0x40(SP) + AND $(0xF<<2), R26 + SUB $(CSYS<<2), R26 + + JAL saveregs(SB) + + MOVW $setR30(SB), R30 + SUBU $(UREGADDR-2*BY2WD-USERADDR), SP, R(USER) + MOVW $MPID, R1 + MOVB 3(R1), R1 + MOVW $MACHADDR, R(MACH) /* locn of mach 0 */ + AND $7, R1 + SLL $PGSHIFT, R1 + ADDU R1, R(MACH) /* add offset for mach # */ + + BNE R26, notsys + + JAL syscall(SB) + + MOVW 0x28(SP), R31 + MOVW 0x08(SP), R26 + MOVW 0x2C(SP), R30 + MOVW R26, M(STATUS) + NOOP + MOVW 0x0C(SP), R26 /* old pc */ + MOVW 0x10(SP), SP + RFE (R26) + +notsys: + JAL trap(SB) + +restore: + JAL restregs(SB) + MOVW 0x28(SP), R31 + MOVW 0x2C(SP), R30 + MOVW 0x3C(SP), R(MACH) + MOVW 0x40(SP), R(USER) + MOVW 0x10(SP), SP + RFE (R26) + +waskernel: + MOVW $1, R26 /* not sys call */ + MOVW SP, -0x90(SP) /* drop this if possible */ + SUB $0xA0, SP + MOVW R31, 0x28(SP) + JAL saveregs(SB) + JAL trap(SB) + JAL restregs(SB) + MOVW 0x28(SP), R31 + ADD $0xA0, SP + RFE (R26) + +TEXT saveregs(SB), $-4 + MOVW R1, 0x9C(SP) + MOVW R2, 0x98(SP) + ADDU $8, SP, R1 + MOVW R1, 0x04(SP) /* arg to base of regs */ + MOVW M(STATUS), R1 + MOVW M(EPC), R2 + MOVW R1, 0x08(SP) + MOVW R2, 0x0C(SP) + + BEQ R26, return /* sys call, don't save */ + + MOVW M(CAUSE), R1 + MOVW M(BADVADDR), R2 + MOVW R1, 0x14(SP) + MOVW M(TLBVIRT), R1 + MOVW R2, 0x18(SP) + MOVW R1, 0x1C(SP) + MOVW HI, R1 + MOVW LO, R2 + MOVW R1, 0x20(SP) + MOVW R2, 0x24(SP) + /* LINK,SB,SP missing */ + MOVW R28, 0x30(SP) + /* R27, R26 not saved */ + /* R25, R24 missing */ + MOVW R23, 0x44(SP) + MOVW R22, 0x48(SP) + MOVW R21, 0x4C(SP) + MOVW R20, 0x50(SP) + MOVW R19, 0x54(SP) + MOVW R18, 0x58(SP) + MOVW R17, 0x5C(SP) + MOVW R16, 0x60(SP) + MOVW R15, 0x64(SP) + MOVW R14, 0x68(SP) + MOVW R13, 0x6C(SP) + MOVW R12, 0x70(SP) + MOVW R11, 0x74(SP) + MOVW R10, 0x78(SP) + MOVW R9, 0x7C(SP) + MOVW R8, 0x80(SP) + MOVW R7, 0x84(SP) + MOVW R6, 0x88(SP) + MOVW R5, 0x8C(SP) + MOVW R4, 0x90(SP) + MOVW R3, 0x94(SP) +return: + RET + +TEXT restregs(SB), $-4 + /* LINK,SB,SP missing */ + MOVW 0x30(SP), R28 + /* R27, R26 not saved */ + /* R25, R24 missing */ + MOVW 0x44(SP), R23 + MOVW 0x48(SP), R22 + MOVW 0x4C(SP), R21 + MOVW 0x50(SP), R20 + MOVW 0x54(SP), R19 + MOVW 0x58(SP), R18 + MOVW 0x5C(SP), R17 + MOVW 0x60(SP), R16 + MOVW 0x64(SP), R15 + MOVW 0x68(SP), R14 + MOVW 0x6C(SP), R13 + MOVW 0x70(SP), R12 + MOVW 0x74(SP), R11 + MOVW 0x78(SP), R10 + MOVW 0x7C(SP), R9 + MOVW 0x80(SP), R8 + MOVW 0x84(SP), R7 + MOVW 0x88(SP), R6 + MOVW 0x8C(SP), R5 + MOVW 0x90(SP), R4 + MOVW 0x94(SP), R3 + MOVW 0x24(SP), R2 + MOVW 0x20(SP), R1 + MOVW R2, LO + MOVW R1, HI + MOVW 0x08(SP), R1 + MOVW 0x98(SP), R2 + MOVW R1, M(STATUS) + NOOP + MOVW 0x9C(SP), R1 + MOVW 0x0C(SP), R26 /* old pc */ + RET + +TEXT rfnote(SB), $0 + MOVW 0(FP), R26 /* 1st arg is &uregpointer */ + SUBU $(BY2WD), R26, SP /* pc hole */ + BNE R26, restore + + +TEXT clrfpintr(SB), $0 + MOVW FCR31, R1 + MOVW R1, R2 + AND $~(0x3F<<12), R2 + MOVW R2, FCR31 + RET + +TEXT savefpregs(SB), $0 + MOVW M(STATUS), R3 + MOVW 0(FP), R1 + MOVW FCR31, R2 + + MOVD F0, 0x00(R1) + MOVD F2, 0x08(R1) + MOVD F4, 0x10(R1) + MOVD F6, 0x18(R1) + MOVD F8, 0x20(R1) + MOVD F10, 0x28(R1) + MOVD F12, 0x30(R1) + MOVD F14, 0x38(R1) + MOVD F16, 0x40(R1) + MOVD F18, 0x48(R1) + MOVD F20, 0x50(R1) + MOVD F22, 0x58(R1) + MOVD F24, 0x60(R1) + MOVD F26, 0x68(R1) + MOVD F28, 0x70(R1) + MOVD F30, 0x78(R1) + + MOVW R2, 0x80(R1) + AND $~CU1, R3 + MOVW R3, M(STATUS) + RET + +TEXT restfpregs(SB), $0 + + MOVW M(STATUS), R3 + MOVW 0(FP), R1 + OR $CU1, R3 + MOVW R3, M(STATUS) + MOVW 0x80(R1), R2 + + MOVD 0x00(R1), F0 + MOVD 0x08(R1), F2 + MOVD 0x10(R1), F4 + MOVD 0x18(R1), F6 + MOVD 0x20(R1), F8 + MOVD 0x28(R1), F10 + MOVD 0x30(R1), F12 + MOVD 0x38(R1), F14 + MOVD 0x40(R1), F16 + MOVD 0x48(R1), F18 + MOVD 0x50(R1), F20 + MOVD 0x58(R1), F22 + MOVD 0x60(R1), F24 + MOVD 0x68(R1), F26 + MOVD 0x70(R1), F28 + MOVD 0x78(R1), F30 + + MOVW R2, FCR31 + AND $~CU1, R3 + MOVW R3, M(STATUS) + RET + +/* + * we avoid using R4, R5, R6, and R7 so gotopc can call us without saving them + */ +TEXT icflush(SB), $-4 /* icflush(physaddr, nbytes) */ + + MOVW M(STATUS), R10 + MOVW 0(FP), R8 + MOVW 4(FP), R9 + MOVW $KSEG0, R3 + OR R3, R8 + MOVW $0, M(STATUS) + MOVW $WBFLUSH, R1 /* wbflush */ + MOVW 0(R1), R1 + NOOP + MOVW $KSEG1, R3 + MOVW $icflush0(SB), R2 /* make sure PC is in uncached address space */ + MOVW $(SWC|ISC), R1 + OR R3, R2 + JMP (R2) + +TEXT icflush0(SB), $-4 + + MOVW R1, M(STATUS) /* swap and isolate cache, splhi */ + MOVW $icflush1(SB), R2 + JMP (R2) + +TEXT icflush1(SB), $-4 + +_icflush1: + MOVBU R0, 0x00(R8) + MOVBU R0, 0x04(R8) + MOVBU R0, 0x08(R8) + MOVBU R0, 0x0C(R8) + MOVBU R0, 0x10(R8) + MOVBU R0, 0x14(R8) + MOVBU R0, 0x18(R8) + MOVBU R0, 0x1C(R8) + MOVBU R0, 0x20(R8) + MOVBU R0, 0x24(R8) + MOVBU R0, 0x28(R8) + MOVBU R0, 0x2C(R8) + MOVBU R0, 0x30(R8) + MOVBU R0, 0x34(R8) + MOVBU R0, 0x38(R8) + MOVBU R0, 0x3C(R8) + SUB $0x40, R9 + ADD $0x40, R8 + BGTZ R9, _icflush1 + MOVW $icflush2(SB), R2 /* make sure PC is in uncached address space */ + OR R3, R2 + JMP (R2) + +TEXT icflush2(SB), $-4 + + MOVW $0, M(STATUS) /* swap back caches, de-isolate them, and stay splhi */ + NOOP /* +++ */ + MOVW R10, M(STATUS) + RET + +TEXT dcflush(SB), $-4 /* dcflush(physaddr, nbytes) */ + + MOVW M(STATUS), R6 + MOVW 0(FP), R4 + MOVW 4(FP), R5 + MOVW $KSEG0, R3 + OR R3, R4 + MOVW $0, M(STATUS) + MOVW $WBFLUSH, R1 + MOVW 0(R1), R1 + NOOP + MOVW $ISC, R1 + MOVW R1, M(STATUS) +_dcflush0: + MOVBU R0, 0x00(R4) + MOVBU R0, 0x04(R4) + MOVBU R0, 0x08(R4) + MOVBU R0, 0x0C(R4) + MOVBU R0, 0x10(R4) + MOVBU R0, 0x14(R4) + MOVBU R0, 0x18(R4) + MOVBU R0, 0x1C(R4) + MOVBU R0, 0x20(R4) + MOVBU R0, 0x24(R4) + MOVBU R0, 0x28(R4) + MOVBU R0, 0x2C(R4) + MOVBU R0, 0x30(R4) + MOVBU R0, 0x34(R4) + MOVBU R0, 0x38(R4) + MOVBU R0, 0x3C(R4) + SUB $0x40, R5 + ADD $0x40, R4 + BGTZ R5, _dcflush0 + MOVW $0, M(STATUS) + NOOP /* +++ */ + MOVW R6, M(STATUS) + RET diff --git a/sys/src/cmd/va/lex.c b/sys/src/cmd/va/lex.c new file mode 100755 index 000000000..61448d2eb --- /dev/null +++ b/sys/src/cmd/va/lex.c @@ -0,0 +1,702 @@ +#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 = 'v'; + thestring = "mips"; + 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; + case 'L': /* for little-endian mips */ + thechar = '0'; + thestring = "spim"; + 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, + "HI", LHI, D_HI, + "LO", LLO, D_LO, + + "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, + + "M", LM, 0, + "M0", LMREG, 0, + "M1", LMREG, 1, + "M2", LMREG, 2, + "M3", LMREG, 3, + "M4", LMREG, 4, + "M5", LMREG, 5, + "M6", LMREG, 6, + "M7", LMREG, 7, + "M8", LMREG, 8, + "M9", LMREG, 9, + "M10", LMREG, 10, + "M11", LMREG, 11, + "M12", LMREG, 12, + "M13", LMREG, 13, + "M14", LMREG, 14, + "M15", LMREG, 15, + "M16", LMREG, 16, + "M17", LMREG, 17, + "M18", LMREG, 18, + "M19", LMREG, 19, + "M20", LMREG, 20, + "M21", LMREG, 21, + "M22", LMREG, 22, + "M23", LMREG, 23, + "M24", LMREG, 24, + "M25", LMREG, 25, + "M26", LMREG, 26, + "M27", LMREG, 27, + "M28", LMREG, 28, + "M29", LMREG, 29, + "M30", LMREG, 30, + "M31", LMREG, 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, + + "FCR", LFCR, 0, + "FCR0", LFCREG, 0, + "FCR1", LFCREG, 1, + "FCR2", LFCREG, 2, + "FCR3", LFCREG, 3, + "FCR4", LFCREG, 4, + "FCR5", LFCREG, 5, + "FCR6", LFCREG, 6, + "FCR7", LFCREG, 7, + "FCR8", LFCREG, 8, + "FCR9", LFCREG, 9, + "FCR10", LFCREG, 10, + "FCR11", LFCREG, 11, + "FCR12", LFCREG, 12, + "FCR13", LFCREG, 13, + "FCR14", LFCREG, 14, + "FCR15", LFCREG, 15, + "FCR16", LFCREG, 16, + "FCR17", LFCREG, 17, + "FCR18", LFCREG, 18, + "FCR19", LFCREG, 19, + "FCR20", LFCREG, 20, + "FCR21", LFCREG, 21, + "FCR22", LFCREG, 22, + "FCR23", LFCREG, 23, + "FCR24", LFCREG, 24, + "FCR25", LFCREG, 25, + "FCR26", LFCREG, 26, + "FCR27", LFCREG, 27, + "FCR28", LFCREG, 28, + "FCR29", LFCREG, 29, + "FCR30", LFCREG, 30, + "FCR31", LFCREG, 31, + + "ADD", LTYPE1, AADD, + "ADDU", LTYPE1, AADDU, + "SUB", LTYPE1, ASUB, /* converted to ADD(-) in loader */ + "SUBU", LTYPE1, ASUBU, + "SGT", LTYPE1, ASGT, + "SGTU", LTYPE1, ASGTU, + "AND", LTYPE1, AAND, + "OR", LTYPE1, AOR, + "XOR", LTYPE1, AXOR, + "SLL", LTYPE1, ASLL, + "SRL", LTYPE1, ASRL, + "SRA", LTYPE1, ASRA, + + "ADDV", LTYPE1, AADDV, + "ADDVU", LTYPE1, AADDVU, + "SUBV", LTYPE1, ASUBV, /* converted to ADD(-) in loader */ + "SUBVU", LTYPE1, ASUBVU, + "SLLV", LTYPE1, ASLLV, + "SRLV", LTYPE1, ASRLV, + "SRAV", LTYPE1, ASRAV, + + "NOR", LTYPE2, ANOR, + + "MOVB", LTYPE3, AMOVB, + "MOVBU", LTYPE3, AMOVBU, + "MOVH", LTYPE3, AMOVH, + "MOVHU", LTYPE3, AMOVHU, + "MOVWL", LTYPE3, AMOVWL, + "MOVWR", LTYPE3, AMOVWR, + "MOVVL", LTYPE3, AMOVVL, + "MOVVR", LTYPE3, AMOVVR, + + "BREAK", LTYPEJ, ABREAK, /* overloaded CACHE opcode */ + "END", LTYPE4, AEND, + "REM", LTYPE6, AREM, + "REMU", LTYPE6, AREMU, + "RET", LTYPE4, ARET, + "SYSCALL", LTYPE4, ASYSCALL, + "TLBP", LTYPE4, ATLBP, + "TLBR", LTYPE4, ATLBR, + "TLBWI", LTYPE4, ATLBWI, + "TLBWR", LTYPE4, ATLBWR, + + "MOVW", LTYPE5, AMOVW, + "MOVV", LTYPE5, AMOVV, + "MOVD", LTYPE5, AMOVD, + "MOVF", LTYPE5, AMOVF, + + "DIV", LTYPE6, ADIV, + "DIVU", LTYPE6, ADIVU, + "MUL", LTYPE6, AMUL, + "MULU", LTYPE6, AMULU, + "DIVV", LTYPE6, ADIVV, + "DIVVU", LTYPE6, ADIVVU, + "MULV", LTYPE6, AMULV, + "MULVU", LTYPE6, AMULVU, + + "RFE", LTYPE7, ARFE, + "JMP", LTYPE7, AJMP, + + "JAL", LTYPE8, AJAL, + + "BEQ", LTYPE9, ABEQ, + "BNE", LTYPE9, ABNE, + + "BGEZ", LTYPEA, ABGEZ, + "BGEZAL", LTYPEA, ABGEZAL, + "BGTZ", LTYPEA, ABGTZ, + "BLEZ", LTYPEA, ABLEZ, + "BLTZ", LTYPEA, ABLTZ, + "BLTZAL", LTYPEA, ABLTZAL, + + "TEXT", LTYPEB, ATEXT, + "GLOBL", LTYPEB, AGLOBL, + + "DATA", LTYPEC, ADATA, + + "MOVDF", LTYPE5, AMOVDF, + "MOVDW", LTYPE5, AMOVDW, + "MOVFD", LTYPE5, AMOVFD, + "MOVFW", LTYPE5, AMOVFW, + "MOVWD", LTYPE5, AMOVWD, + "MOVWF", LTYPE5, AMOVWF, + + "ABSD", LTYPED, AABSD, + "ABSF", LTYPED, AABSF, + "ABSW", LTYPED, AABSW, + "NEGD", LTYPED, ANEGD, + "NEGF", LTYPED, ANEGF, + "NEGW", LTYPED, ANEGW, + + "CMPEQD", LTYPEF, ACMPEQD, + "CMPEQF", LTYPEF, ACMPEQF, + "CMPGED", LTYPEF, ACMPGED, + "CMPGEF", LTYPEF, ACMPGEF, + "CMPGTD", LTYPEF, ACMPGTD, + "CMPGTF", LTYPEF, ACMPGTF, + + "ADDD", LTYPEE, AADDD, + "ADDF", LTYPEE, AADDF, + "ADDW", LTYPEE, AADDW, + "DIVD", LTYPEE, ADIVD, + "DIVF", LTYPEE, ADIVF, + "DIVW", LTYPEE, ADIVW, + "MULD", LTYPEE, AMULD, + "MULF", LTYPEE, AMULF, + "MULW", LTYPEE, AMULW, + "SUBD", LTYPEE, ASUBD, + "SUBF", LTYPEE, ASUBF, + "SUBW", LTYPEE, ASUBW, + + "BFPT", LTYPEG, ABFPT, + "BFPF", LTYPEG, ABFPF, + + "WORD", LTYPEH, AWORD, + "NOP", LTYPEI, ANOP, + "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; + 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; +} + +int +isreg(Gen *g) +{ + + USED(g); + return 1; +} + +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_MREG: + case D_FCREG: + case D_LO: + case D_HI: + break; + + case D_OREG: + case D_CONST: + case D_OCONST: + 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; +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/va/mkfile b/sys/src/cmd/va/mkfile new file mode 100755 index 000000000..170c66b89 --- /dev/null +++ b/sys/src/cmd/va/mkfile @@ -0,0 +1,19 @@ +</$objtype/mkfile + +TARG=va +OFILES=\ + y.tab.$O\ + lex.$O\ + +HFILES=\ + ../vc/v.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 |