diff options
Diffstat (limited to 'utils/ka/a.y')
| -rw-r--r-- | utils/ka/a.y | 734 |
1 files changed, 734 insertions, 0 deletions
diff --git a/utils/ka/a.y b/utils/ka/a.y new file mode 100644 index 00000000..4d927203 --- /dev/null +++ b/utils/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; + } |
