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/7a |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/7a')
-rwxr-xr-x | sys/src/cmd/7a/a.h | 208 | ||||
-rwxr-xr-x | sys/src/cmd/7a/a.y | 537 | ||||
-rwxr-xr-x | sys/src/cmd/7a/lex.c | 694 | ||||
-rwxr-xr-x | sys/src/cmd/7a/mkfile | 19 |
4 files changed, 1458 insertions, 0 deletions
diff --git a/sys/src/cmd/7a/a.h b/sys/src/cmd/7a/a.h new file mode 100755 index 000000000..bb44001a2 --- /dev/null +++ b/sys/src/cmd/7a/a.h @@ -0,0 +1,208 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "../7c/7.out.h" + +#ifndef EXTERN +#define EXTERN extern +#endif + +#define MAXALIGN 7 + +typedef struct Sym Sym; +typedef struct Ref Ref; +typedef struct Gen Gen; +typedef struct Io Io; +typedef struct Hist Hist; + +#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 + +#define ALLOC(lhs, type)\ + while(nhunk < sizeof(type))\ + gethunk();\ + lhs = (type*)hunk;\ + nhunk -= sizeof(type);\ + hunk += sizeof(type); + +#define ALLOCN(lhs, len, n)\ + if(lhs+len != hunk || nhunk < n) {\ + while(nhunk <= len)\ + gethunk();\ + memmove(hunk, lhs, len);\ + lhs = hunk;\ + hunk += len;\ + nhunk -= len;\ + }\ + hunk += n;\ + nhunk -= n; + +struct Sym +{ + Sym* link; + Ref* ref; + char* macro; + vlong value; + long dummy_pad; + ushort type; + char *name; + char sym; +}; +#define S ((Sym*)0) + +struct Ref +{ + int class; +}; + +struct +{ + char* p; + int c; +} fi; + +struct Io +{ + Io* link; + char b[BUFSIZ]; + char* p; + short c; + short f; +}; +#define I ((Io*)0) + +struct +{ + Sym* sym; + short type; +} h[NSYM]; + +struct Gen +{ + Sym* sym; + vlong offset; + long dummy_pad; + short type; + short reg; + short name; + double dval; + char sval[8]; +}; + +struct Hist +{ + Hist* link; + char* name; + long line; + vlong offset; +}; +#define H ((Hist*)0) + +enum +{ + CLAST, + CMACARG, + CMACRO, + CPREPROC, +}; + +char debug[256]; +Sym* hash[NHASH]; +char* Dlist[30]; +int nDlist; +Hist* ehist; +int newflag; +Hist* hist; +char* hunk; +char* include[NINCLUDE]; +Io* iofree; +Io* ionext; +Io* iostack; +long lineno; +int nerrors; +long nhunk; +int ninclude; +Gen nullgen; +char* outfile; +int pass; +char* pathname; +vlong pc; +int peekc; +int sym; +char symb[NSYMB]; +int thechar; +char* thestring; +long thunk; +Biobuf obuf; + +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/7a/a.y b/sys/src/cmd/7a/a.y new file mode 100755 index 000000000..8e0565032 --- /dev/null +++ b/sys/src/cmd/7a/a.y @@ -0,0 +1,537 @@ +%{ +#include "a.h" +%} +%union +{ + Sym *sym; + vlong 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 LPREG LPCC +%token <lval> LTYPEX LREG LFREG LFPCR LR LP LF +%token <dval> LFCONST +%token <sval> LSCONST +%token <sym> LNAME LLAB LVAR +%type <lval> con expr pointer offset sreg +%type <gen> gen vgen lgen vlgen flgen rel reg freg preg fcreg +%type <gen> imm ximm ireg name oreg imr nireg fgen pcc +%% +prog: +| prog line + +line: + LLAB ':' + { + if($1->value != pc) + yyerror("redeclaration of %s", $1->name); + $1->value = pc; + } + line +| LNAME ':' + { + $1->type = LLAB; + $1->value = pc; + } + line +| LNAME '=' expr ';' + { + $1->type = LVAR; + $1->value = $3; + } +| LVAR '=' expr ';' + { + if($1->value != $3) + yyerror("redeclaration of %s", $1->name); + $1->value = $3; + } +| ';' +| inst ';' +| error ';' + +inst: +/* + * Integer operates + */ + LTYPE1 imr ',' sreg ',' reg + { + outcode($1, &$2, $4, &$6); + } +| LTYPE1 imr ',' reg + { + outcode($1, &$2, NREG, &$4); + } +/* + * floating-type + */ +| LTYPE2 freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LTYPE3 freg ',' freg + { + outcode($1, &$2, NREG, &$4); + } +| LTYPE3 freg ',' LFREG ',' freg + { + outcode($1, &$2, $4, &$6); + } +/* + * MOVQ + */ +| LTYPE4 vlgen ',' vgen + { + if(!isreg(&$2) && !isreg(&$4)) + print("one side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * integer LOAD/STORE, but not MOVQ + */ +| LTYPE5 lgen ',' gen + { + if(!isreg(&$2) && !isreg(&$4)) + print("one side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * integer LOAD/STORE (only) + */ +| LTYPE6 oreg ',' reg + { + outcode($1, &$2, NREG, &$4); + } +| LTYPEK reg ',' oreg + { + outcode($1, &$2, NREG, &$4); + } +/* + * floating LOAD/STORE + */ +| LTYPE7 flgen ',' fgen + { + if(!isreg(&$2) && !isreg(&$4)) + print("one side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * JMP/JSR/RET + */ +| LTYPE8 comma rel + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPE8 comma nireg + { + outcode($1, &nullgen, NREG, &$3); + } +| LTYPE8 sreg ',' nireg + { + outcode($1, &nullgen, $2, &$4); + } +| LTYPE9 comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +/* + * integer conditional branches + */ +| LTYPEA gen ',' rel + { + if(!isreg(&$2)) + print("left side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * floating conditional branches + */ +| LTYPEB fgen ',' rel + { + if(!isreg(&$2)) + print("left side must be register\n"); + outcode($1, &$2, NREG, &$4); + } +/* + * TRAPB/MB/REI + */ +| LTYPEC comma + { + outcode($1, &nullgen, NREG, &nullgen); + } +/* + * FETCH/FETCHM + */ +| LTYPED ireg comma + { + outcode($1, &$2, NREG, &nullgen); + } +/* + * Call-pal + */ +| LTYPEE imm + { + outcode($1, &$2, NREG, &nullgen); + } +/* + * TEXT/GLOBL + */ +| LTYPEF name ',' imm + { + outcode($1, &$2, NREG, &$4); + } +| LTYPEF name ',' con ',' imm + { + outcode($1, &$2, $4, &$6); + } +/* + * DATA + */ +| LTYPEG name '/' con ',' ximm + { + outcode($1, &$2, $4, &$6); + } +/* + * 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); + } + +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 +| preg +| pcc + +vgen: + gen +| preg + +lgen: + gen +| ximm + +flgen: + fgen +| ximm + +fgen: + gen +| freg +| fcreg + +preg: + LPREG + { + $$ = nullgen; + $$.type = D_PREG; + $$.reg = $1; + } +| LP '(' con ')' + { + $$ = nullgen; + $$.type = D_PREG; + $$.reg = $1+$3; + } + +fcreg: + LFPCR + { + $$ = nullgen; + $$.type = D_FCREG; + $$.reg = $1; + } + +freg: + LFREG + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $1; + } +| LF '(' con ')' + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $3; + } + +pcc: + LPCC + { + $$ = nullgen; + $$.type = D_PCC; + $$.reg = $1; + } + +ximm: '$' con + { + $$ = nullgen; + $$.type = D_CONST; + $$.offset = $2; + } +| '$' oreg + { + $$ = $2; + $$.type = D_CONST; + } +| '$' 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 +| 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/7a/lex.c b/sys/src/cmd/7a/lex.c new file mode 100755 index 000000000..30cfd2417 --- /dev/null +++ b/sys/src/cmd/7a/lex.c @@ -0,0 +1,694 @@ +#include <ctype.h> +#define EXTERN +#include "a.h" +#include "y.tab.h" + +void +main(int argc, char *argv[]) +{ + char ofile[100], incfile[20], *p; + int nout, nproc, status, i, c, of; + + thechar = '7'; /* of 9 */ + thestring = "alpha"; + 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(); + if(p) + include[ninclude++] = p; + break; + } ARGEND + if(*argv == 0) { + print("usage: %ca [-options] file.s\n", thechar); + errorexit(); + } + nproc = 3; + if(p = getenv("NPROC")) + nproc = atol(p); + if(argc > 1) { + c = 0; + nout = 0; + for(;;) { + while(nout < nproc && argc > 0) { + i = fork(); + if(i < 0) { + i = mywait(&status); + if(i < 0) + errorexit(); + if(status) + c++; + nout--; + continue; + } + if(i == 0) { + print("%s:\n", *argv); + goto child; + } + nout++; + argc--; + argv++; + } + i = mywait(&status); + if(i < 0) { + if(c) + errorexit(); + exits(0); + } + if(status) + c++; + nout--; + } + } + +child: + strecpy(ofile, ofile+sizeof ofile, *argv); + if(p = strrchr(ofile, '/')) { + include[0] = ofile; + *p++ = 0; + } else + p = ofile; + if(outfile == 0) { + outfile = p; + if(p = strrchr(outfile, '.')) + if(p[1] == 's' && p[2] == 0) + p[0] = 0; + p = strrchr(outfile, 0); + p[0] = '.'; + p[1] = thechar; + p[2] = 0; + } + if(0) { + strcpy(incfile, "/usr/%include"); + p = strrchr(incfile, '%'); + if(p) + *p = thechar; + } else { + strcpy(incfile, "/"); + strcat(incfile, thestring); + strcat(incfile, "/include"); + } + include[ninclude++] = incfile; + if(p = getenv("INCLUDE")) + include[ninclude-1] = p; /* */ + of = mycreat(outfile, 0664); + if(of < 0) { + yyerror("%ca: cannot create %s", thechar, outfile); + errorexit(); + } + Binit(&obuf, of, OWRITE); + + pass = 1; + pinit(*argv); + for(i=0; i<nDlist; i++) + dodefine(Dlist[i]); + yyparse(); + if(nerrors) { + cclean(); + errorexit(); + } + + pass = 2; + outhist(); + pinit(*argv); + for(i=0; i<nDlist; i++) + dodefine(Dlist[i]); + yyparse(); + cclean(); + if(nerrors) + errorexit(); + exits(0); +} + +struct +{ + char *name; + ushort type; + ushort value; +} itab[] = +{ + "SP", LSP, D_AUTO, + "SB", LSB, D_EXTERN, + "FP", LFP, D_PARAM, + "PC", LPC, D_BRANCH, + + "R", LR, 0, + "R0", LREG, 0, + "R1", LREG, 1, + "R2", LREG, 2, + "R3", LREG, 3, + "R4", LREG, 4, + "R5", LREG, 5, + "R6", LREG, 6, + "R7", LREG, 7, + "R8", LREG, 8, + "R9", LREG, 9, + "R10", LREG, 10, + "R11", LREG, 11, + "R12", LREG, 12, + "R13", LREG, 13, + "R14", LREG, 14, + "R15", LREG, 15, + "R16", LREG, 16, + "R17", LREG, 17, + "R18", LREG, 18, + "R19", LREG, 19, + "R20", LREG, 20, + "R21", LREG, 21, + "R22", LREG, 22, + "R23", LREG, 23, + "R24", LREG, 24, + "R25", LREG, 25, + "R26", LREG, 26, + "R27", LREG, 27, + "R28", LREG, 28, + "R29", LREG, 29, + "R30", LREG, 30, + "R31", LREG, 31, + + "P", LP, 0, + "I", LP, 32, + "A", LP, 64, + "IA", LP, 96, + "T", LP, 128, + "IT", LP, 32+128, + "AT", LP, 64+128, + "IAT", LP, 96+128, + "T0", LPREG, 0+128, + "T1", LPREG, 1+128, + "T2", LPREG, 2+128, + "T3", LPREG, 3+128, + "T4", LPREG, 4+128, + "T5", LPREG, 5+128, + "T6", LPREG, 6+128, + "T7", LPREG, 7+128, + "T8", LPREG, 8+128, + "T9", LPREG, 9+128, + "T10", LPREG, 10+128, + "T11", LPREG, 11+128, + "T12", LPREG, 12+128, + "T13", LPREG, 13+128, + "T14", LPREG, 14+128, + "T15", LPREG, 15+128, + "T16", LPREG, 16+128, + "T17", LPREG, 17+128, + "T18", LPREG, 18+128, + "T19", LPREG, 19+128, + "T20", LPREG, 20+128, + "T21", LPREG, 21+128, + "T22", LPREG, 22+128, + "T23", LPREG, 23+128, + "T24", LPREG, 24+128, + "T25", LPREG, 25+128, + "T26", LPREG, 26+128, + "T27", LPREG, 27+128, + "T28", LPREG, 28+128, + "T29", LPREG, 29+128, + "T30", LPREG, 30+128, + "T31", LPREG, 31+128, + + "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, + + "FPCR", LFPCR, 0, + "PCC", LPCC, 0, + + /* 1: integer operates */ + "ADDQ", LTYPE1, AADDQ, + "ADDL", LTYPE1, AADDL, + "SUBL", LTYPE1, ASUBL, + "SUBQ", LTYPE1, ASUBQ, + "CMPEQ", LTYPE1, ACMPEQ, + "CMPGT", LTYPE1, ACMPGT, + "CMPGE", LTYPE1, ACMPGE, + "CMPUGT", LTYPE1, ACMPUGT, + "CMPUGE", LTYPE1, ACMPUGE, + "CMPBLE", LTYPE1, ACMPBLE, + + "AND", LTYPE1, AAND, + "ANDNOT", LTYPE1, AANDNOT, + "OR", LTYPE1, AOR, + "ORNOT", LTYPE1, AORNOT, + "XOR", LTYPE1, AXOR, + "XORNOT", LTYPE1, AXORNOT, + + "CMOVEQ", LTYPE1, ACMOVEQ, + "CMOVNE", LTYPE1, ACMOVNE, + "CMOVLT", LTYPE1, ACMOVLT, + "CMOVGE", LTYPE1, ACMOVGE, + "CMOVLE", LTYPE1, ACMOVLE, + "CMOVGT", LTYPE1, ACMOVGT, + "CMOVLBS", LTYPE1, ACMOVLBS, + "CMOVLBC", LTYPE1, ACMOVLBC, + + "MULL", LTYPE1, AMULL, + "MULQ", LTYPE1, AMULQ, + "UMULH", LTYPE1, AUMULH, + "DIVQ", LTYPE1, ADIVQ, + "MODQ", LTYPE1, AMODQ, + "DIVQU", LTYPE1, ADIVQU, + "MODQU", LTYPE1, AMODQU, + "DIVL", LTYPE1, ADIVL, + "MODL", LTYPE1, AMODL, + "DIVLU", LTYPE1, ADIVLU, + "MODLU", LTYPE1, AMODLU, + + "SLLQ", LTYPE1, ASLLQ, + "SRLQ", LTYPE1, ASRLQ, + "SRAQ", LTYPE1, ASRAQ, + + "SLLL", LTYPE1, ASLLL, + "SRLL", LTYPE1, ASRLL, + "SRAL", LTYPE1, ASRAL, + + "EXTBL", LTYPE1, AEXTBL, + "EXTWL", LTYPE1, AEXTWL, + "EXTLL", LTYPE1, AEXTLL, + "EXTQL", LTYPE1, AEXTQL, + "EXTWH", LTYPE1, AEXTWH, + "EXTLH", LTYPE1, AEXTLH, + "EXTQH", LTYPE1, AEXTQH, + + "INSBL", LTYPE1, AINSBL, + "INSWL", LTYPE1, AINSWL, + "INSLL", LTYPE1, AINSLL, + "INSQL", LTYPE1, AINSQL, + "INSWH", LTYPE1, AINSWH, + "INSLH", LTYPE1, AINSLH, + "INSQH", LTYPE1, AINSQH, + + "MSKBL", LTYPE1, AMSKBL, + "MSKWL", LTYPE1, AMSKWL, + "MSKLL", LTYPE1, AMSKLL, + "MSKQL", LTYPE1, AMSKQL, + "MSKWH", LTYPE1, AMSKWH, + "MSKLH", LTYPE1, AMSKLH, + "MSKQH", LTYPE1, AMSKQH, + + "ZAP", LTYPE1, AZAP, + "ZAPNOT", LTYPE1, AZAPNOT, + + /* 2: floating operates with 2 operands */ + "CVTQS", LTYPE2, ACVTQS, + "CVTQT", LTYPE2, ACVTQT, + "CVTTS", LTYPE2, ACVTTS, + "CVTTQ", LTYPE2, ACVTTQ, + "CVTLQ", LTYPE2, ACVTLQ, + "CVTQL", LTYPE2, ACVTQL, + + /* 3: floating operates with 2 or 3 operands */ + "CPYS", LTYPE3, ACPYS, + "CPYSN", LTYPE3, ACPYSN, + "CPYSE", LTYPE3, ACPYSE, + "ADDS", LTYPE3, AADDS, + "ADDT", LTYPE3, AADDT, + "CMPTEQ", LTYPE3, ACMPTEQ, + "CMPTGT", LTYPE3, ACMPTGT, + "CMPTGE", LTYPE3, ACMPTGE, + "CMPTUN", LTYPE3, ACMPTUN, + "DIVS", LTYPE3, ADIVS, + "DIVT", LTYPE3, ADIVT, + "MULS", LTYPE3, AMULS, + "MULT", LTYPE3, AMULT, + "SUBS", LTYPE3, ASUBS, + "SUBT", LTYPE3, ASUBT, + "FCMOVEQ", LTYPE3, AFCMOVEQ, + "FCMOVNE", LTYPE3, AFCMOVNE, + "FCMOVLT", LTYPE3, AFCMOVLT, + "FCMOVGE", LTYPE3, AFCMOVGE, + "FCMOVLE", LTYPE3, AFCMOVLE, + "FCMOVGT", LTYPE3, AFCMOVGT, + + /* 4: integer load/store and reg->reg (incl special regs) */ + "MOVQ", LTYPE4, AMOVQ, + + /* 5: integer load/store and reg->reg */ + "MOVL", LTYPE5, AMOVL, + "MOVQU", LTYPE5, AMOVQU, + "MOVB", LTYPE5, AMOVB, + "MOVBU", LTYPE5, AMOVBU, + "MOVW", LTYPE5, AMOVW, + "MOVWU", LTYPE5, AMOVWU, + "MOVLP", LTYPE5, AMOVLP, + "MOVQP", LTYPE5, AMOVQP, + + /* 6: integer load/store (only) */ + "MOVA", LTYPE6, AMOVA, + "MOVAH", LTYPE6, AMOVAH, + "MOVLL", LTYPE6, AMOVLL, + "MOVQL", LTYPE6, AMOVQL, + "MOVLC", LTYPEK, AMOVLC, + "MOVQC", LTYPEK, AMOVQC, + + /* 7: floating load/store and reg->reg */ + "MOVS", LTYPE7, AMOVS, + "MOVT", LTYPE7, AMOVT, + + /* 8,9: jumps */ + "JMP", LTYPE8, AJMP, + "JSR", LTYPE8, AJSR, + "RET", LTYPE9, ARET, + + /* A: integer conditional branches */ + "BEQ", LTYPEA, ABEQ, + "BNE", LTYPEA, ABNE, + "BLT", LTYPEA, ABLT, + "BGE", LTYPEA, ABGE, + "BLE", LTYPEA, ABLE, + "BGT", LTYPEA, ABGT, + "BLBC", LTYPEA, ABLBC, + "BLBS", LTYPEA, ABLBS, + + /* B: floating conditional branches */ + "FBEQ", LTYPEB, AFBEQ, + "FBNE", LTYPEB, AFBNE, + "FBLT", LTYPEB, AFBLT, + "FBGE", LTYPEB, AFBGE, + "FBLE", LTYPEB, AFBLE, + "FBGT", LTYPEB, AFBGT, + + /* C-J: miscellaneous */ + "TRAPB", LTYPEC, ATRAPB, + "MB", LTYPEC, AMB, + "REI", LTYPEC, AREI, + "END", LTYPEC, AEND, + "FETCH", LTYPED, AFETCH, + "FETCHM", LTYPED, AFETCHM, + "CALL_PAL", LTYPEE, ACALL_PAL, + "TEXT", LTYPEF, ATEXT, + "GLOBL", LTYPEF, AGLOBL, + "DATA", LTYPEG, ADATA, + "WORD", LTYPEH, AWORD, + "NOP", LTYPEI, ANOP, + 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; + } + + ALLOCN(pathname, 0, 100); + if(getwd(pathname, 99) == 0) { + ALLOCN(pathname, 100, 900); + if(getwd(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) +{ + vlong 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_PREG: + case D_FCREG: + case D_PCC: + break; + + case D_OREG: + case D_CONST: + case D_BRANCH: + l = a->offset; + Bputc(&obuf, l); + Bputc(&obuf, l>>8); + Bputc(&obuf, l>>16); + Bputc(&obuf, l>>24); + Bputc(&obuf, l>>32); + Bputc(&obuf, l>>40); + Bputc(&obuf, l>>48); + Bputc(&obuf, l>>56); + 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); + 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; + int n; + + g = nullgen; + for(h = hist; h != H; h = h->link) { + p = h->name; + op = 0; + if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { + op = p; + p = pathname; + } + while(p) { + q = strchr(p, '/'); + if(q) { + n = q-p; + if(n == 0) + n = 1; /* leading "/" */ + 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/7a/mkfile b/sys/src/cmd/7a/mkfile new file mode 100755 index 000000000..e48fbea48 --- /dev/null +++ b/sys/src/cmd/7a/mkfile @@ -0,0 +1,19 @@ +</$objtype/mkfile + +TARG=7a +OFILES=\ + y.tab.$O\ + lex.$O\ + +HFILES=\ + ../7c/7.out.h\ + y.tab.h\ + a.h\ + +YFILES=a.y\ + +BIN=/$objtype/bin +< /sys/src/cmd/mkone +YFLAGS=-D1 -d + +lex.$O: ../cc/macbody ../cc/lexbody |