diff options
| author | Richard Miller <miller.research@gmail.com> | 2020-11-09 11:36:14 +0000 |
|---|---|---|
| committer | Richard Miller <miller.research@gmail.com> | 2020-11-09 11:36:14 +0000 |
| commit | 6e84dc968bc4eaf047fbefcba2f670940718dda8 (patch) | |
| tree | 523d2f81946b1e0abe4afddf1d2fce7e1525b7d7 /utils/ia | |
| parent | 2a571cc0ece4073eb56d5ccfc3e061a09a353e13 (diff) | |
Add toolchain for riscv (ia ic il) and riscv64 (ja jc jl)
Because the rv64 ISA is very nearly a proper superset of rv32, the
compilers ic and jc are actually the same program, which compiles
to .i or .j depending on how it is invoked; similarly for ia/ja and
il/jl. It is also possible to invoke ia/ic/il with a '-j' option to
specify 64-bit behaviour.
Diffstat (limited to 'utils/ia')
| -rw-r--r-- | utils/ia/a.h | 181 | ||||
| -rw-r--r-- | utils/ia/a.y | 514 | ||||
| -rw-r--r-- | utils/ia/lex.c | 642 | ||||
| -rw-r--r-- | utils/ia/mkfile | 31 |
4 files changed, 1368 insertions, 0 deletions
diff --git a/utils/ia/a.h b/utils/ia/a.h new file mode 100644 index 00000000..32c27f17 --- /dev/null +++ b/utils/ia/a.h @@ -0,0 +1,181 @@ +#include <lib9.h> +#include <bio.h> +#include "../ic/i.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 name; + double dval; + char sval[8]; + vlong vval; +}; + +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/utils/ia/a.y b/utils/ia/a.y new file mode 100644 index 00000000..e7470860 --- /dev/null +++ b/utils/ia/a.y @@ -0,0 +1,514 @@ +%{ +#include "a.h" +%} +%union +{ + Sym *sym; + vlong lval; + double dval; + char sval[8]; + Gen gen; +} +%left '|' +%left '^' +%left '&' +%left '<' '>' +%left '+' '-' +%left '*' '/' '%' +%token <lval> LADD LMUL LBEQ LBR LBRET LCALL LFLT2 LFLT3 +%token <lval> LMOVB LMOVBU LMOVW LMOVF LLUI LSYS LSYS0 LCSR LSWAP LAMO +%token <lval> LCONST LSP LSB LFP LPC LREG LFREG LR FR LCTL +%token <lval> LDATA LTEXT LWORD +%token <sval> LSCONST +%token <dval> LFCONST +%token <sym> LNAME LLAB LVAR +%type <lval> con expr pointer offset sreg freg oprrr +%type <gen> rreg dreg ctlreg drreg +%type <gen> addr name oreg rel imm ximm fimm +%% +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: + LADD imm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| oprrr rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LADD imm ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } +| oprrr rreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } + +| LFLT2 drreg ',' drreg + { + outcode($1, &$2, NREG, &$4); + } +| LFLT3 drreg ',' freg ',' drreg + { + outcode($1, &$2, $4, &$6); + } + +| LBEQ rreg ',' sreg ',' rel + { + outcode($1, &$2, $4, &$6); + } + +| LBEQ rreg ',' rel + { + Gen regzero; + regzero = nullgen; + regzero.type = D_REG; + regzero.reg = 0; + outcode($1, ®zero, $2.reg, &$4); + } + +| LBR rel + { + outcode($1, &nullgen, NREG, &$2); + } + +| LBR oreg + { + outcode($1, &nullgen, NREG, &$2); + } + + +| LBRET + { + outcode($1, &nullgen, NREG, &nullgen); + } + +| LCALL sreg ',' addr + { + outcode($1, &nullgen, $2, &$4); + } +| LCALL sreg ',' rel + { + outcode($1, &nullgen, $2, &$4); + } + +| LMOVB addr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVBU addr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVB rreg ',' addr + { + outcode($1, &$2, NREG, &$4); + } + +| LMOVF addr ',' dreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVF dreg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVF dreg ',' dreg + { + outcode($1, &$2, NREG, &$4); + } + + +| LMOVW imm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW ximm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW addr ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' addr + { + outcode($1, &$2, NREG, &$4); + } +| LMOVW rreg ',' ctlreg + { + Gen regzero; + regzero = nullgen; + regzero.type = D_REG; + regzero.reg = 0; + outcode(ACSRRW, &$4, $2.reg, ®zero); + } +| LMOVW imm ',' ctlreg + { + Gen regzero; + int r = $2.offset; + if(r < 0 || r >= NREG) + yyerror("immediate value out of range"); + regzero = nullgen; + regzero.type = D_REG; + regzero.reg = 0; + outcode(ACSRRWI, &$4, r, ®zero); + } +| LMOVW ctlreg ',' rreg + { + outcode(ACSRRS, &$2, REGZERO, &$4); + } + +| LLUI name ',' rreg + { + outcode($1, &$2, NREG, &$4); + } +| LLUI imm ',' rreg + { + outcode($1, &$2, NREG, &$4); + } + + +| LSYS imm + { + outcode($1, &nullgen, NREG, &$2); + } + +| LSYS0 + { + Gen syscon; + syscon = nullgen; + syscon.type = D_CONST; + syscon.offset = $1; + outcode(ASYS, &nullgen, NREG, &syscon); + } + +| LCSR ctlreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } + +| LCSR ctlreg ',' '$' con ',' rreg + { + if($5 < 0 || $5 >= NREG) + yyerror("immediate value out of range"); + outcode($1 + (ACSRRWI-ACSRRW), &$2, $5, &$7); + } + +| LSWAP rreg ',' sreg ',' rreg + { + outcode($1, &$2, $4, &$6); + } + +| LAMO con ',' rreg ',' sreg ',' rreg + { + outcode($1, &$4, ($2<<16)|$6, &$8); + } + +| LTEXT name ',' imm + { + outcode($1, &$2, NREG, &$4); + } +| LTEXT name ',' con ',' imm + { + outcode($1, &$2, $4, &$6); + } + +| 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); + } + +| LWORD imm + { + outcode($1, &nullgen, NREG, &$2); + } + +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; + } + +oprrr: + LADD +| LMUL + +addr: + oreg +| name + +oreg: + '(' sreg ')' + { + $$ = nullgen; + $$.type = D_OREG; + $$.reg = $2; + $$.offset = 0; + } +| 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; + } + +offset: + { + $$ = 0; + } +| '+' con + { + $$ = $2; + } +| '-' con + { + $$ = -$2; + } + +pointer: + LSB +| LSP +| LFP + +rreg: + sreg + { + $$ = nullgen; + $$.type = D_REG; + $$.reg = $1; + } + +dreg: + freg + { + $$ = nullgen; + $$.type = D_FREG; + $$.reg = $1; + } + +drreg: + dreg +| rreg + +sreg: + LREG +| LR '(' expr ')' + { + if($3 < 0 || $3 >= NREG) + yyerror("register value out of range"); + $$ = $3; + } + +freg: + LFREG +| FR '(' expr ')' + { + if($3 < 0 || $3 >= NREG) + yyerror("register value out of range"); + $$ = $3; + } + +ctlreg: + LCTL '(' expr ')' + { + if($3 < 0 || $3 >= 0xFFF) + yyerror("CSR value out of range"); + $$ = nullgen; + $$.type = D_CTLREG; + $$.offset = $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; + if(thechar == 'j' && (vlong)$$.offset != $2){ + $$.type = D_VCONST; + $$.vval = $2; + } + } + +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/utils/ia/lex.c b/utils/ia/lex.c new file mode 100644 index 00000000..ac12f42d --- /dev/null +++ b/utils/ia/lex.c @@ -0,0 +1,642 @@ +#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 = 'i'; + p = strrchr(argv[0], '/'); + if(p == nil) + p = argv[0]; + else + p++; + if(*p == 'j') + thechar = 'j'; + 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(debug['j']) + thechar = 'j'; + thestring = (thechar == 'j'? "riscv64" : "riscv"); + 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); + if(thechar == 'j') + dodefine("XLEN=8"); + else + dodefine("XLEN=4"); + for(i=0; i<nDlist; i++) + dodefine(Dlist[i]); + yyparse(); + if(nerrors) { + cclean(); + return nerrors; + } + + pass = 2; + outhist(); + pinit(file); + if(thechar == 'j') + dodefine("XLEN=8"); + else + dodefine("XLEN=4"); + 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, + + "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, + + "F", FR, 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, + + "CSR", LCTL, 0, + + "ADD", LADD, AADD, + "SLL", LADD, ASLL, + "SLT", LADD, ASLT, + "SLTU", LADD, ASLTU, + "XOR", LADD, AXOR, + "SRL", LADD, ASRL, + "OR", LADD, AOR, + "AND", LADD, AAND, + "SRA", LADD, ASRA, + "ADDW", LADD, AADDW, + "SLLW", LADD, ASLLW, + "SRLW", LADD, ASRLW, + "SRAW", LADD, ASRAW, + "SUB", LADD, ASUB, + "SUBW", LADD, ASUBW, + + "MUL", LMUL, AMUL, + "MULH", LMUL, AMULH, + "MULHSU", LMUL, AMULHSU, + "MULHU", LMUL, AMULHU, + "DIV", LMUL, ADIV, + "DIVU", LMUL, ADIVU, + "REM", LMUL, AREM, + "REMU", LMUL, AREMU, + "MULW", LMUL, AMULW, + "DIVW", LMUL, ADIVW, + "DIVUW", LMUL, ADIVUW, + "REMW", LMUL, AREMW, + "REMUW", LMUL, AREMUW, + + "BEQ", LBEQ, ABEQ, + "BNE", LBEQ, ABNE, + "BLT", LBEQ, ABLT, + "BGE", LBEQ, ABGE, + "BLTU", LBEQ, ABLTU, + "BGEU", LBEQ, ABGEU, + "BGT", LBEQ, ABGT, + "BGTU", LBEQ, ABGTU, + "BLE", LBEQ, ABLE, + "BLEU", LBEQ, ABLEU, + + "JMP", LBR, AJMP, + + "RET", LBRET, ARET, + "FENCE_I", LBRET, AFENCE_I, + "NOP", LBRET, ANOP, + "END", LBRET, AEND, + + "JAL", LCALL, AJAL, + "JALR", LCALL, AJAL, + + "MOVB", LMOVB, AMOVB, + "MOVH", LMOVB, AMOVH, + + "MOVF", LMOVF, AMOVF, + "MOVD", LMOVF, AMOVD, + + "MOVBU", LMOVBU, AMOVBU, + "MOVHU", LMOVBU, AMOVHU, + + "MOVW", LMOVW, AMOVW, + + "MOVFD", LFLT2, AMOVFD, + "MOVDF", LFLT2, AMOVDF, + "MOVWF", LFLT2, AMOVWF, + "MOVUF", LFLT2, AMOVUF, + "MOVFW", LFLT2, AMOVFW, + "MOVWD", LFLT2, AMOVWD, + "MOVUD", LFLT2, AMOVUD, + "MOVDW", LFLT2, AMOVDW, + "ADDF", LFLT3, AADDF, + "ADDD", LFLT3, AADDD, + "SUBF", LFLT3, ASUBF, + "SUBD", LFLT3, ASUBD, + "MULF", LFLT3, AMULF, + "MULD", LFLT3, AMULD, + "DIVF", LFLT3, ADIVF, + "DIVD", LFLT3, ADIVD, + "CMPLTF", LFLT3, ACMPLTF, + "CMPLTD", LFLT3, ACMPLTD, + "CMPEQF", LFLT3, ACMPEQF, + "CMPEQD", LFLT3, ACMPEQD, + "CMPLEF", LFLT3, ACMPLEF, + "CMPLED", LFLT3, ACMPLED, + + "LUI", LLUI, ALUI, + + "SYS", LSYS, ASYS, + "ECALL", LSYS0, 0, + "EBREAK", LSYS0, 1, + "CSRRW", LCSR, ACSRRW, + "CSRRS", LCSR, ACSRRS, + "CSRRC", LCSR, ACSRRC, + + "SWAP_W", LSWAP, ASWAP_W, + "SWAP_D", LSWAP, ASWAP_D, + "LR_W", LSWAP, ALR_W, + "LR_D", LSWAP, ALR_D, + "SC_W", LSWAP, ASC_W, + "SC_D", LSWAP, ASC_D, + + "AMO_W", LAMO, AAMO_W, + "AMO_D", LAMO, AAMO_D, + + "DATA", LDATA, ADATA, + "GLOBL", LTEXT, AGLOBL, + "TEXT", LTEXT, ATEXT, + "WORD", LWORD, AWORD, + "DWORD", LWORD, ADWORD, + + "MOV", LMOVW, AMOV, + "MOVWU", LMOVBU, AMOVWU, + + 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; +} + +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 v; + 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: + break; + + case D_CTLREG: + 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); + break; + + case D_VCONST: + v = a->vval; + Bputc(&obuf, v); + Bputc(&obuf, v>>8); + Bputc(&obuf, v>>16); + Bputc(&obuf, v>>24); + Bputc(&obuf, v>>32); + Bputc(&obuf, v>>40); + Bputc(&obuf, v>>48); + Bputc(&obuf, v>>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, 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" diff --git a/utils/ia/mkfile b/utils/ia/mkfile new file mode 100644 index 00000000..05ccc4dc --- /dev/null +++ b/utils/ia/mkfile @@ -0,0 +1,31 @@ +<../../mkconfig + +TARG=ia # also makes ja (for riscv64) + +OFILES=\ + y.tab.$O\ + lex.$O\ + +HFILES=\ + ../ic/i.out.h\ + y.tab.h\ + a.h\ + +YFILES=a.y\ + +LIBS=cc bio 9 # order is important + +BIN=$ROOT/$OBJDIR/bin +<$ROOT/mkfiles/mkone-$SHELLTYPE + +YFLAGS=-D1 -d +CFLAGS= $CFLAGS -I../include + +lex.$O: ../cc/macbody ../cc/lexbody + +$ROOT/$OBJDIR/lib/libcc.a: + cd ../cc + mk $MKFLAGS install + mk $MKFLAGS clean + +install:V: $BIN/ja |
