123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 |
- %{
- #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> LTYPEL LTYPEM LTYPEN LTYPEBX
- %token <lval> LCONST LSP LSB LFP LPC
- %token <lval> LTYPEX LR LREG LF LFREG LC LCREG LPSR LFCR
- %token <lval> LCOND LS LAT
- %token <dval> LFCONST
- %token <sval> LSCONST
- %token <sym> LNAME LLAB LVAR
- %type <lval> con expr oexpr pointer offset sreg spreg creg
- %type <lval> rcon cond reglist
- %type <gen> gen rel reg regreg freg shift fcon frcon
- %type <gen> imm ximm name oreg ireg nireg ioreg imsr
- %%
- 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:
- /*
- * ADD
- */
- LTYPE1 cond imsr ',' spreg ',' reg
- {
- outcode($1, $2, &$3, $5, &$7);
- }
- | LTYPE1 cond imsr ',' spreg ','
- {
- outcode($1, $2, &$3, $5, &nullgen);
- }
- | LTYPE1 cond imsr ',' reg
- {
- outcode($1, $2, &$3, NREG, &$5);
- }
- /*
- * MVN
- */
- | LTYPE2 cond imsr ',' reg
- {
- outcode($1, $2, &$3, NREG, &$5);
- }
- /*
- * MOVW
- */
- | LTYPE3 cond gen ',' gen
- {
- outcode($1, $2, &$3, NREG, &$5);
- }
- /*
- * B/BL
- */
- | LTYPE4 cond comma rel
- {
- outcode($1, $2, &nullgen, NREG, &$4);
- }
- | LTYPE4 cond comma nireg
- {
- outcode($1, $2, &nullgen, NREG, &$4);
- }
- /*
- * BX
- */
- | LTYPEBX comma ireg
- {
- outcode($1, Always, &nullgen, NREG, &$3);
- }
- /*
- * BEQ
- */
- | LTYPE5 comma rel
- {
- outcode($1, Always, &nullgen, NREG, &$3);
- }
- /*
- * SWI
- */
- | LTYPE6 cond comma gen
- {
- outcode($1, $2, &nullgen, NREG, &$4);
- }
- /*
- * CMP
- */
- | LTYPE7 cond imsr ',' spreg comma
- {
- outcode($1, $2, &$3, $5, &nullgen);
- }
- /*
- * MOVM
- */
- | LTYPE8 cond ioreg ',' '[' reglist ']'
- {
- Gen g;
- g = nullgen;
- g.type = D_CONST;
- g.offset = $6;
- outcode($1, $2, &$3, NREG, &g);
- }
- | LTYPE8 cond '[' reglist ']' ',' ioreg
- {
- Gen g;
- g = nullgen;
- g.type = D_CONST;
- g.offset = $4;
- outcode($1, $2, &g, NREG, &$7);
- }
- /*
- * SWAP
- */
- | LTYPE9 cond reg ',' ireg ',' reg
- {
- outcode($1, $2, &$5, $3.reg, &$7);
- }
- | LTYPE9 cond reg ',' ireg comma
- {
- outcode($1, $2, &$5, $3.reg, &$3);
- }
- | LTYPE9 cond comma ireg ',' reg
- {
- outcode($1, $2, &$4, $6.reg, &$6);
- }
- /*
- * RET
- */
- | LTYPEA cond comma
- {
- outcode($1, $2, &nullgen, NREG, &nullgen);
- }
- /*
- * TEXT/GLOBL
- */
- | LTYPEB name ',' imm
- {
- outcode($1, Always, &$2, NREG, &$4);
- }
- | LTYPEB name ',' con ',' imm
- {
- outcode($1, Always, &$2, $4, &$6);
- }
- /*
- * DATA
- */
- | LTYPEC name '/' con ',' ximm
- {
- outcode($1, Always, &$2, $4, &$6);
- }
- /*
- * CASE
- */
- | LTYPED cond reg comma
- {
- outcode($1, $2, &$3, NREG, &nullgen);
- }
- /*
- * word
- */
- | LTYPEH comma ximm
- {
- outcode($1, Always, &nullgen, NREG, &$3);
- }
- /*
- * floating-point coprocessor
- */
- | LTYPEI cond freg ',' freg
- {
- outcode($1, $2, &$3, NREG, &$5);
- }
- | LTYPEK cond frcon ',' freg
- {
- outcode($1, $2, &$3, NREG, &$5);
- }
- | LTYPEK cond frcon ',' LFREG ',' freg
- {
- outcode($1, $2, &$3, $5, &$7);
- }
- | LTYPEL cond freg ',' freg comma
- {
- outcode($1, $2, &$3, $5.reg, &nullgen);
- }
- /*
- * MCR MRC
- */
- | LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
- {
- Gen g;
- g = nullgen;
- g.type = D_CONST;
- g.offset =
- (0xe << 24) | /* opcode */
- ($1 << 20) | /* MCR/MRC */
- ($2 << 28) | /* scond */
- (($3 & 15) << 8) | /* coprocessor number */
- (($5 & 7) << 21) | /* coprocessor operation */
- (($7 & 15) << 12) | /* arm register */
- (($9 & 15) << 16) | /* Crn */
- (($11 & 15) << 0) | /* Crm */
- (($12 & 7) << 5) | /* coprocessor information */
- (1<<4); /* must be set */
- outcode(AWORD, Always, &nullgen, NREG, &g);
- }
- /*
- * MULL hi,lo,r1,r2
- */
- | LTYPEM cond reg ',' reg ',' regreg
- {
- outcode($1, $2, &$3, $5.reg, &$7);
- }
- /*
- * MULA hi,lo,r1,r2
- */
- | LTYPEN cond reg ',' reg ',' reg ',' spreg
- {
- $7.type = D_REGREG;
- $7.offset = $9;
- outcode($1, $2, &$3, $5.reg, &$7);
- }
- /*
- * END
- */
- | LTYPEE comma
- {
- outcode($1, Always, &nullgen, NREG, &nullgen);
- }
- cond:
- {
- $$ = Always;
- }
- | cond LCOND
- {
- $$ = ($1 & ~C_SCOND) | $2;
- }
- | cond LS
- {
- $$ = $1 | $2;
- }
- comma:
- | ',' 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;
- }
- 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));
- }
- | fcon
- fcon:
- '$' LFCONST
- {
- $$ = nullgen;
- $$.type = D_FCONST;
- $$.dval = $2;
- }
- | '$' '-' LFCONST
- {
- $$ = nullgen;
- $$.type = D_FCONST;
- $$.dval = -$3;
- }
- reglist:
- spreg
- {
- $$ = 1 << $1;
- }
- | spreg '-' spreg
- {
- int i;
- $$=0;
- for(i=$1; i<=$3; i++)
- $$ |= 1<<i;
- for(i=$3; i<=$1; i++)
- $$ |= 1<<i;
- }
- | spreg comma reglist
- {
- $$ = (1<<$1) | $3;
- }
- gen:
- reg
- | ximm
- | shift
- | shift '(' spreg ')'
- {
- $$ = $1;
- $$.reg = $3;
- }
- | LPSR
- {
- $$ = nullgen;
- $$.type = D_PSR;
- $$.reg = $1;
- }
- | LFCR
- {
- $$ = nullgen;
- $$.type = D_FPCR;
- $$.reg = $1;
- }
- | con
- {
- $$ = nullgen;
- $$.type = D_OREG;
- $$.offset = $1;
- }
- | oreg
- | freg
- nireg:
- ireg
- | name
- {
- $$ = $1;
- if($1.name != D_EXTERN && $1.name != D_STATIC) {
- }
- }
- ireg:
- '(' spreg ')'
- {
- $$ = nullgen;
- $$.type = D_OREG;
- $$.reg = $2;
- $$.offset = 0;
- }
- ioreg:
- ireg
- | con '(' sreg ')'
- {
- $$ = nullgen;
- $$.type = D_OREG;
- $$.reg = $3;
- $$.offset = $1;
- }
- oreg:
- name
- | name '(' sreg ')'
- {
- $$ = $1;
- $$.type = D_OREG;
- $$.reg = $3;
- }
- | ioreg
- imsr:
- reg
- | imm
- | shift
- imm: '$' con
- {
- $$ = nullgen;
- $$.type = D_CONST;
- $$.offset = $2;
- }
- reg:
- spreg
- {
- $$ = nullgen;
- $$.type = D_REG;
- $$.reg = $1;
- }
- regreg:
- '(' spreg ',' spreg ')'
- {
- $$ = nullgen;
- $$.type = D_REGREG;
- $$.reg = $2;
- $$.offset = $4;
- }
- shift:
- spreg '<' '<' rcon
- {
- $$ = nullgen;
- $$.type = D_SHIFT;
- $$.offset = $1 | $4 | (0 << 5);
- }
- | spreg '>' '>' rcon
- {
- $$ = nullgen;
- $$.type = D_SHIFT;
- $$.offset = $1 | $4 | (1 << 5);
- }
- | spreg '-' '>' rcon
- {
- $$ = nullgen;
- $$.type = D_SHIFT;
- $$.offset = $1 | $4 | (2 << 5);
- }
- | spreg LAT '>' rcon
- {
- $$ = nullgen;
- $$.type = D_SHIFT;
- $$.offset = $1 | $4 | (3 << 5);
- }
- rcon:
- spreg
- {
- if($$ < 0 || $$ >= 16)
- print("register value out of range\n");
- $$ = (($1&15) << 8) | (1 << 4);
- }
- | con
- {
- if($$ < 0 || $$ >= 32)
- print("shift value out of range\n");
- $$ = ($1&31) << 7;
- }
- sreg:
- LREG
- | LPC
- {
- $$ = REGPC;
- }
- | LR '(' expr ')'
- {
- if($3 < 0 || $3 >= NREG)
- print("register value out of range\n");
- $$ = $3;
- }
- spreg:
- sreg
- | LSP
- {
- $$ = REGSP;
- }
- creg:
- LCREG
- | LC '(' expr ')'
- {
- if($3 < 0 || $3 >= NREG)
- print("register value out of range\n");
- $$ = $3;
- }
- frcon:
- freg
- | fcon
- freg:
- LFREG
- {
- $$ = nullgen;
- $$.type = D_FREG;
- $$.reg = $1;
- }
- | LF '(' con ')'
- {
- $$ = nullgen;
- $$.type = D_FREG;
- $$.reg = $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;
- }
- oexpr:
- {
- $$ = 0;
- }
- | ',' 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;
- }
|