123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992 |
- %{
- #ifndef NORCSID
- static char rcsid[]= "$Header$";
- #endif
- #include "param.h"
- #include "varinfo.h"
- #include "lookup.h"
- #include "set.h"
- #include "iocc.h"
- #include "instruct.h"
- #include "expr.h"
- #include "extern.h"
- #include <cgg_cg.h>
- #include <em_reg.h>
- extern int lineno;
- int instline,saveline;
- int startline;
- int npatterns;
- int patindex[MAXPATTERNS];
- int emhere=0; /* lexical analyzer flag */
- int optexact=0; /* Inside "with exact" rule */
- int optstack=0; /* Inside with <blah> STACK rule */
- int saferulefound=0;
- int maxempatlen=0;
- int maxrule=0;
- struct varinfo *defcost;
- struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
- struct varinfo *make_erase();
- expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr();
- expr_t perc_ident_expr(),sum_expr(),regvar_expr();
- set_t ident_to_set(),setproduct(),setsum(),setdiff();
- iocc_t subr_iocc(),tokm_iocc(),ident_iocc(),all_iocc(),descr_iocc();
- extern int narexpr;
- extern expr_t arexp[];
- int niops;
- iocc_t iops[20];
- %}
- %union {
- int yy_int;
- char * yy_str;
- varinfo * yy_varinfo;
- set_t yy_set;
- operand *yy_oplist;
- expr_t yy_expr;
- iocc_t yy_iocc;
- }
- %token PROPERTIES
- %token REGISTERS
- %token TOKENS
- %token SETS
- %token MOVES
- %token TESTS
- %token STACKINGRULES COERCIONS
- %token INSTRUCTIONS
- %token PROC CALL EXAMPLE
- %token FROM TO
- %token TEST MOVE STACK RETURN
- %token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING
- %token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW
- %token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP
- %token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER
- %token <yy_int> ADORNACCESS
- %token <yy_int> ADORNCC
- %token INT
- %token ADDR
- %token <yy_int> EMMNEM
- %token <yy_int> NUMBER
- %token <yy_int> DOLLAR PERCENT ALLREG
- %token <yy_str> IDENT PERC_IDENT
- %token <yy_str> STRING
- %token TIMEFACTOR SIZEFACTOR
- %token COST
- %type <yy_varinfo> prop_list property ident_list ident_list_el
- %type <yy_varinfo> att_list att_list_el structdecl optcost optformat
- %type <yy_varinfo> kills allocates yields leaving
- %type <yy_varinfo> generates kill_list kill_list_el uselist uselist_el genlist yieldlist
- %type <yy_varinfo> leavelist leavelist_el gen_instruction
- %type <yy_varinfo> opt_erase_list erase_list erase_list_el
- %type <yy_str> opt_par_string optstring
- %type <yy_int> register propno att_list_el_type tokenset_no
- %type <yy_int> adornlist optstar optuses optregvar regvartype optregvartype
- %type <yy_int> emarg tokarg subreg allreg optsecondstring
- %type <yy_expr> expr
- %type <yy_iocc> tokeninstance
- %type <yy_int> optexpr optexact optstack
- %type <yy_set> tokenset
- %type <yy_oplist> oplist oplist_el
- %left OR2
- %left AND2
- %left CMPEQ,CMPNE
- %left CMPLT,CMPLE,CMPGT,CMPGE
- %left RSHIFT,LSHIFT
- %left '+','-'
- %left '*','/','%'
- %nonassoc NOT,COMP,UMINUS
- %start machtable
- %%
- /*
- * The machine table consists of a number of sections, with their
- * own associated parsers.
- */
- machtable
- : constants
- properties
- registers
- tokens
- { make_std_sets(); }
- sets
- instructions
- moves
- tests
- stacks
- coercs
- code
- ;
- /*
- * Constants are parsed as name=value pairs
- */
- constants
- : constdeflist
- ;
- constdeflist
- : /* empty */
- | constdeflist constdef
- ;
- constdef
- : IDENT'=' NUMBER
- { n_const($1,$3); free($1); }
- | IDENT '=' STRING
- { n_sconst($1,$3); free($1); free($3); }
- | TIMEFACTOR '=' NUMBER '/' NUMBER
- { fc1 = $3; fc2 = $5; }
- | SIZEFACTOR '=' NUMBER '/' NUMBER
- { fc3 = $3; fc4 = $5; }
- | error
- ;
- /*
- * Properties are parsed as a list of names optionally followed by their size
- */
- properties
- : PROPERTIES { make_const(); } prdef_list
- ;
- prdef_list
- : prdef_list_el
- | prdef_list optcomma prdef_list_el
- ;
- prdef_list_el
- : IDENT
- { n_prop($1,wordsize); free($1); }
- | IDENT '(' NUMBER ')'
- { n_prop($1,$3); free($1); }
- ;
- /*
- * Registers are rows of reglist:proplist pairs
- */
- registers
- : REGISTERS regdef_list
- ;
- regdef_list
- : regdef_list_el
- | regdef_list regdef_list_el
- ;
- regdef_list_el
- : ident_list ':' prop_list optregvar '.'
- { regline($1,$3,$4); free((char *) $1); free((char *) $3); }
- | error '.'
- ;
- optregvar
- : /* empty */
- { $$ = -1; }
- | REGVAR
- { $$ = reg_any; }
- | REGVAR '(' regvartype ')'
- { $$ = $3; }
- ;
- regvartype
- : REG_ANY
- { $$ = reg_any;}
- | REG_FLOAT
- { $$ = reg_float;}
- | REG_LOOP
- { $$ = reg_loop;}
- | REG_POINTER
- { $$ = reg_pointer;}
- ;
- ident_list
- : ident_list_el
- | ident_list optcomma ident_list_el
- { $3->vi_next = $1; $$ = $3; }
- ;
- ident_list_el
- : IDENT opt_par_string
- { NEW($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = n_reg($1,$2,0,0,0);
- free($1); if($2!=0) free($2);
- }
- | IDENT opt_par_string '=' register
- { NEW($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = n_reg($1,$2,1,$4,0);
- free($1); if($2!=0) free($2);
- }
- | IDENT opt_par_string '=' register '+' register
- { NEW($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = n_reg($1,$2,2,$4,$6);
- free($1); if($2!=0) free($2);
- }
- ;
- opt_par_string
- : /* empty */
- { $$ = 0; }
- | '(' STRING ')'
- { $$ = $2; }
- ;
- register
- : IDENT
- { register symbol *sy_p;
- sy_p = lookup($1,symreg,mustexist);
- $$ = sy_p->sy_value.syv_regno;
- free($1);
- }
- ;
- prop_list
- : property
- | prop_list optcomma property
- { $3->vi_next = $1; $$ = $3; }
- ;
- property
- : IDENT
- { register symbol *sy_p;
- sy_p = lookup($1,symprop,mustexist);
- NEW($$,struct varinfo);
- $$->vi_next=0;
- $$->vi_int[0]=sy_p->sy_value.syv_propno;
- free($1);
- }
- ;
- propno
- : IDENT
- { register symbol *sy_p;
- sy_p = lookup($1,symprop,mustexist);
- $$ = sy_p->sy_value.syv_propno;
- free($1);
- }
- ;
- /* tokens are parsed as struct definitions
- * types in the struct can be register properties, ADDR or INT
- */
- tokens
- : TOKENS tokdeflist
- ;
- tokdeflist
- : tokdeflist_el
- | tokdeflist tokdeflist_el
- ;
- tokdeflist_el
- : IDENT '=' structdecl NUMBER optcost optformat '.'
- { n_tok($1,$3,$4,$5,$6);
- free($1);
- freevi($3);
- freevi($5);
- freevi($6);
- }
- | error '.'
- ;
- structdecl
- : '{' att_list '}'
- { $$ = $2; }
- ;
- att_list
- : /* empty */
- { $$ = 0; }
- | att_list_el att_list
- { $1->vi_next = $2; $$ = $1; }
- ;
- att_list_el
- : att_list_el_type IDENT ';'
- { NEW ($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = $1;
- $$->vi_str[0] = $2;
- }
- ;
- att_list_el_type
- : INT
- { $$ = -1; }
- | ADDR
- { $$ = -2; }
- | propno
- ;
- optcost
- :
- { if (defcost==VI_NULL)
- $$=VI_NULL;
- else {
- NEW($$,struct varinfo);
- *$$ = *defcost;
- }
- }
- | COST '(' NUMBER ',' NUMBER ')'
- { NEW ($$,struct varinfo);
- $$->vi_int[0] = $3;
- $$->vi_int[1] = $5;
- }
- ;
- optformat
- :
- { $$ = 0; }
- | STRING optformat
- { NEW($$,struct varinfo);
- $$->vi_next = $2;
- $$->vi_int[0] = 0;
- $$->vi_str[0] = $1;
- }
- | IDENT optformat
- { NEW($$,struct varinfo);
- $$->vi_next = $2;
- $$->vi_int[0] = 1;
- $$->vi_str[0] = $1;
- }
- ;
- optcomma
- : ','
- | /* empty */
- ;
- /* sets are parsed as ident = expression */
- sets
- : SETS setdeflist
- ;
- setdeflist
- : setdeflist_el
- | setdeflist setdeflist_el
- ;
- setdeflist_el
- : IDENT '=' tokenset_no '.'
- { n_set($1,$3); free($1); }
- | error '.'
- ;
- tokenset_no
- : tokenset
- { $$ = setlookup($1); }
- ;
- tokenset
- : IDENT
- { $$ = ident_to_set($1); free($1); }
- | tokenset '*' tokenset
- { $$ = setproduct($1,$3); }
- | tokenset '+' tokenset
- { $$ = setsum($1,$3); }
- | tokenset '-' tokenset
- { $$ = setdiff($1,$3); }
- | '(' tokenset ')'
- { $$ = $2; }
- ;
- instructions
- : INSTRUCTIONS optcost instdef_list
- { defcost = $2; }
- ;
- instdef_list
- : instdef_list_el
- | instdef_list instdef_list_el
- ;
- instdef_list_el
- : IDENT optstring oplist opt_erase_list optcost '.'
- { n_instr($1,$2,$3,$4,$5); freevi($5); }
- | error '.'
- ;
- oplist
- : /* empty */
- { $$ = 0; }
- | oplist_el
- | oplist_el ',' oplist
- { $$ = $1; $$->o_next = $3; }
- ;
- oplist_el
- : tokenset_no adornlist
- { NEW($$,struct operand);
- $$->o_next = 0 ;
- $$->o_setno = $1;
- $$->o_adorn = $2;
- checkprintformat($1);
- }
- ;
- adornlist
- : /* empty */
- { $$ = 0; }
- | ADORNACCESS adornlist
- { if ($2&AD_RWMASK)
- error("Only one of :ro,:wo,:rw allowed");
- $$ = $1 | $2;
- }
- | ADORNCC adornlist
- { $$ = $1|$2; }
- ;
- opt_erase_list
- : /* empty */
- { $$ = VI_NULL;}
- | KILLS erase_list
- { $$ = $2; }
- ;
- erase_list
- : erase_list_el
- { $$ = $1; }
- | erase_list_el erase_list
- { $1->vi_next = $2; $$ = $1; }
- ;
- erase_list_el
- : IDENT
- { $$ = make_erase($1); }
- | ADORNCC
- { NEW($$, struct varinfo);
- $$->vi_int[0] = -1;
- $$->vi_next = VI_NULL;
- }
- ;
- /* Now the moves */
- moves
- : MOVES movedeflist
- | /* empty */
- ;
- movedeflist
- : movedeflist_el
- | movedeflist movedeflist_el
- ;
- movedeflist_el
- : FROM
- {startline = lineno; }
- tokenset_no
- { cursetno = $3; }
- optexpr TO tokenset_no
- { cursetno = $7;
- tokpatlen=2;
- tokpatset[0] = $3;
- tokpatset[1] = $7;
- tokpatro[0] = 1;
- }
- optexpr GEN genlist
- { tokpatlen=0;
- tokpatro[0]=0;
- n_move($3,$5,$7,$9,$11);
- freevi($11);
- }
- | error
- ;
- /* Now the test part */
- tests
- : TESTS testdeflist
- | /* empty */
- ;
- testdeflist
- : testdeflist_el
- | testdeflist testdeflist_el
- ;
- testdeflist_el
- : TO
- { startline = lineno;}
- TEST tokenset_no
- { cursetno = $4;
- tokpatlen=1;
- tokpatset[0]=$4;
- tokpatro[0] = 1;
- }
- optexpr GEN genlist
- { tokpatlen=0;
- tokpatro[0] = 0;
- n_test($4,$6,$8);
- freevi($8);
- }
- | error
- ;
-
- /* Now the stacks */
- stacks
- : STACKINGRULES stackdeflist
- ;
- stackdeflist
- : stackdeflist_el
- | stackdeflist stackdeflist_el
- ;
- stackdeflist_el
- : FROM
- {startline = lineno;}
- tokenset_no
- { cursetno = $3;
- tokpatlen=1;
- tokpatset[0] = $3;
- tokpatro[0] = 1;
- }
- optexpr TO STACK optuses GEN genlist
- { tokpatro[0] = 0;
- n_stack($3,$5,$8,$10);
- freevi($10);
- }
- ;
- optuses
- : /* empty */
- { $$ = 0; nallreg=0;}
- | USES propno
- { $$ = $2; nallreg = 1; allreg[0] = $2; }
- ;
- /* Now the one-to-one coercion rules */
- coercs
- : COERCIONS coercdeflist
- ;
- coercdeflist
- : coercdeflist_el
- | coercdeflist coercdeflist_el
- ;
- coercdeflist_el
- : FROM
- {startline = lineno; tokpatlen=0; inithall();}
- STACK allocates GEN genlist YIELDS tokeninstance
- { checkhall();
- n_coerc(0,0,$4,$6,(struct varinfo *) 0,$8);
- freevi($4);
- freevi($6);
- }
- | FROM
- {startline = lineno;}
- tokenset_no
- { cursetno = $3;
- tokpatlen=1;
- tokpatset[0]=$3;
- tokpatro[0] = 1;
- inithall();
- }
- optexpr allocates generates yields
- { tokpatro[0] = 0;
- checkhall();
- n_coerc($3,$5,$6,$7,$8);
- freevi($6);
- freevi($7);
- }
- ;
- /* Now the code part */
- code
- : PATTERNS coderules
- ;
- coderules
- : coderule
- | coderules coderule
- ;
- coderule
- : PAT {emhere=1;} empattern {emhere=0;} optexpr
- { empatexpr = $5;
- npatterns = 0;
- saferulefound=0;
- if (empatlen>maxempatlen)
- maxempatlen=empatlen;
- }
- patterns
- { if (!saferulefound)
- error("Previous rule impossible on empty stack");
- outpatterns();
- }
- | PROC IDENT example
- { npatterns = 0; saferulefound=0; inproc=1; n_proc($2); }
- patterns
- { if (!saferulefound)
- error("Previous rule impossible on empty stack");
- outpatterns(); inproc=0;
- }
- | error
- { skipupto(PAT,"pat"); yyerrok; yyclearin; }
- ;
- example
- : /* empty */
- { empatlen = 0; }
- | EXAMPLE {emhere=1;} empattern {emhere=0;}
- ;
- empattern
- : EMMNEM
- { empatlen = 1; emmnem[0] = $1; }
- | empattern EMMNEM
- { NEXT(empatlen,EMPATMAX,"Em pattern");
- emmnem[empatlen-1] = $2;
- }
- ;
- patterns
- : onepattern
- { saferulefound=1;
- callproc=0;
- }
- | morepatterns
- { callproc=0;
- if (npatterns>maxrule)
- maxrule=npatterns;
- }
- | CALL IDENT '(' STRING optsecondstring ')'
- { register symbol *sy_p;
- saferulefound=1;
- sy_p=lookup($2,symproc,mustexist);
- callproc=sy_p->sy_value.syv_procoff;
- procarg[0] = strlookup($4);
- procarg[1] = $5;
- free($2);
- free($4);
- }
- ;
- optsecondstring
- : /* empty */
- { $$ = 0; }
- | ',' STRING
- { $$ = strlookup($2); free($2); }
- ;
- onepattern
- : { inithall(); startline=lineno; tokpatlen=0; }
- kills allocates generates yields leaving
- { optexact=0; optstack=0;
- patindex[npatterns++]=codeindex;
- checkhall();
- dopattern(0,$2,$3,$4,$5,$6);
- freevi($2);
- freevi($3);
- freevi($4);
- freevi($5);
- freevi($6);
- }
- ;
- morepatterns
- : { inithall(); } pattern
- | morepatterns { inithall(); } pattern
- ;
- pattern
- : stackpattern kills allocates generates yields leaving
- { patindex[NEXT(npatterns,MAXPATTERNS,"Patterns")]=codeindex;
- if (hall() && !optexact) saferulefound=1;
- dopattern(0,$2,$3,$4,$5,$6);
- freevi($2);
- freevi($3);
- freevi($4);
- freevi($5);
- freevi($6);
- }
- ;
- stackpattern
- : WITH optexact
- { startline = lineno; }
- setlist optstack
- ;
- optexact
- : /* empty */
- { $$ = optexact = 0; }
- | EXACT
- { $$ = optexact = 1; }
- ;
- optstack
- : /* empty */
- { $$ = optstack = 0; }
- | STACK
- { $$ = optstack = 1; }
- ;
- setlist
- : /* empty */
- { tokpatlen = 0; }
- | setlist tokenset_no
- { NEXT(tokpatlen,TOKPATMAX,"Stack pattern");
- tokpatset[tokpatlen-1] = $2;
- checkunstacking($2);
- }
- ;
- kills
- : /* empty */
- { $$ = 0; }
- | KILLS kill_list
- { $$ = $2;
- if (optstack)
- error("No sense in giving kills in this pattern");
- }
- ;
- kill_list
- : kill_list_el
- | kill_list_el ',' kill_list
- { $$=$1; $$->vi_next = $3; }
- ;
- kill_list_el
- : tokenset_no { cursetno=$1; } optexpr
- { NEW($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0]=$1;
- $$->vi_int[1]=$3;
- }
- ;
- allocates
- : /* empty */
- { $$ = 0; nallreg=0;}
- | USES uselist
- { $$ = $2; setallreg($2); }
- ;
- uselist
- : uselist_el
- { prophall($1->vi_int[0]); }
- | uselist_el ',' uselist
- { prophall($1->vi_int[0]); $$=$1; $$->vi_next=$3; }
- ;
- uselist_el
- : property
- { $$=$1; $$->vi_int[1] = 0; }
- | property '=' tokeninstance
- { if (!existalmove($3,$$->vi_int[0]))
- error("No such move defined");
- $$=$1; $$->vi_int[1] = $3.in_index;
- }
- | REUSING tokeninstance
- { NEW($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = -1;
- $$->vi_int[1] = $2.in_index;
- }
- ;
- generates
- : /* empty */
- { $$ = 0; }
- | GEN genlist
- { $$ = $2; }
- ;
- genlist
- : /* empty */
- { $$ = 0; }
- | gen_instruction genlist
- { if ($1!=0) {
- register struct varinfo *tvip;
- $$=tvip=$1;
- while (tvip->vi_next!=VI_NULL)
- tvip=tvip->vi_next;
- tvip->vi_next = $2;
- } else {
- $$ = $2;
- }
- }
- ;
- gen_instruction
- : {instline = lineno; } IDENT optstar gen_oplist
- { saveline =lineno; lineno=instline;
- $$ = gen_inst($2,$3); free($2);
- lineno = saveline;
- }
- | NUMBER ':'
- { $$ = gen_tlab($1); }
- | MOVE tokeninstance ',' tokeninstance
- { $$ = gen_move($2,$4); }
- | TEST tokeninstance
- { $$ = gen_test($2);}
- | RETURN
- { $$ = gen_preturn(); }
- ;
- optstar
- : /* empty */
- { $$=0; }
- | '*'
- { $$=1; }
- | '[' NUMBER ']'
- { $$=$2; }
- ;
- gen_oplist
- : '.' /* empty gives conflicts */
- { niops=0; }
- | tokeninstance
- { niops=1;iops[0]=$1; }
- | gen_oplist ',' tokeninstance
- { iops[niops++] = $3; }
- ;
- yields
- : /* empty */
- { $$ = 0; }
- | YIELDS yieldlist
- { $$ = $2; }
- ;
- yieldlist
- : /* empty */
- { $$ = 0; }
- | tokeninstance yieldlist
- { checkstacking($1.in_set);
- NEW($$,struct varinfo);
- $$->vi_next = $2;
- $$->vi_int[0] = $1.in_index;
- }
- ;
- leaving
- : /* empty */
- { $$ = 0; }
- | LEAVING {emhere=1; } leavelist
- { emhere=0; $$ = $3; }
- ;
- leavelist
- : leavelist_el
- | leavelist_el leavelist
- { $$=$1; $$->vi_next=$2; }
- ;
- leavelist_el
- : EMMNEM optexpr
- { NEW($$,struct varinfo);
- $$->vi_next=0;
- $$->vi_int[0] = $1;
- $$->vi_int[1] = $2;
- }
- ;
- optstring
- : /* empty */
- { $$ = 0; }
- | STRING
- ;
- optexpr
- : /* empty */
- { $$ = 0; }
- | expr
- { $$ = $1.ex_index; } /* type checking ? */
- ;
- tokeninstance
- : tokarg subreg
- { $$ = subr_iocc($1,$2); }
- | tokarg '.' IDENT
- { $$ = tokm_iocc($1,$3); free($3); }
- | IDENT
- { $$ = ident_iocc($1); free($1);}
- | allreg subreg
- { $$ = all_iocc($1,$2); }
- | '{' IDENT attlist '}'
- { $$ = descr_iocc($2); free($2); }
- ;
- attlist
- : /* empty */
- { narexpr = 0; }
- | attlist ',' expr
- { arexp[narexpr++] = $3; }
- ;
- emarg
- : DOLLAR
- { if ($1<1 || $1>empatlen)
- error("Only %d instructions in pattern",empatlen);
- $$ = $1;
- }
- ;
- tokarg
- : PERCENT
- { if ($1<1 || $1>tokpatlen) {
- error("Only %d tokens in stackpattern",tokpatlen);
- $$ =1;
- } else {
- $$ = $1;
- }
- }
- ;
- subreg
- : /* empty */
- { $$ = 0; }
- | '.' NUMBER
- { if ($2<1 || $2>2) {
- error("Only 2 subregisters allowed");
- $$ = 1;
- } else {
- $$ = $2;
- }
- }
- ;
- allreg
- : ALLREG
- { if ($1>=nallreg)
- fatal("Only %d registers allocated",nallreg);
- $$ = $1;
- }
- ;
- expr
- : NUMBER
- { $$ = make_expr(TYPINT,EX_CON, (int) ($1 & 0xFFFF), (int) ($1>>16));
- }
- | emarg
- { $$ = make_expr(argtyp(emmnem[$1-1]),EX_ARG,$1,0); }
- | STRING
- { $$ = make_expr(TYPADDR,EX_STRING,strlookup($1),0); free($1); }
- | IDENT
- { $$ = ident_expr($1); free($1); }
- | tokarg subreg
- { $$ = subreg_expr($1,$2); }
- | tokarg '.' IDENT
- { $$ = tokm_expr($1,$3); free($3); }
- | allreg subreg
- { $$ = all_expr($1,$2); }
- | PERC_IDENT
- { $$ = perc_ident_expr($1); free($1); }
- | DEFINED '(' expr ')'
- { $$ = make_expr(TYPBOOL,EX_DEFINED,i_expr($3),0); }
- | SAMESIGN '(' expr ',' expr ')'
- { $$ = make_expr(TYPBOOL,EX_SAMESIGN,i_expr($3),i_expr($5)); }
- | SFIT '(' expr ',' expr ')'
- { $$ = make_expr(TYPBOOL,EX_SFIT,i_expr($3),i_expr($5)); }
- | UFIT '(' expr ',' expr ')'
- { $$ = make_expr(TYPBOOL,EX_UFIT,i_expr($3),i_expr($5)); }
- | ROM '(' emarg ',' NUMBER ')'
- { $$ = make_expr(TYPINT,EX_ROM,$3-1,chkincl($5,1,3)-1); }
- | LOWW '(' emarg ')'
- { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
- | HIGHW '(' emarg ')'
- { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
- | '(' expr ')'
- { $$ = $2; }
- | expr CMPEQ expr
- { $$ = make_expr(TYPBOOL,eq2expr($1,$3),$1.ex_index,$3.ex_index); }
- | expr CMPNE expr
- { $$ = make_expr(TYPBOOL,ne2expr($1,$3),$1.ex_index,$3.ex_index); }
- | expr CMPLT expr
- { $$ = make_expr(TYPBOOL,EX_NCPLT,i_expr($1),i_expr($3)); }
- | expr CMPGT expr
- { $$ = make_expr(TYPBOOL,EX_NCPGT,i_expr($1),i_expr($3)); }
- | expr CMPLE expr
- { $$ = make_expr(TYPBOOL,EX_NCPLE,i_expr($1),i_expr($3)); }
- | expr CMPGE expr
- { $$ = make_expr(TYPBOOL,EX_NCPGE,i_expr($1),i_expr($3)); }
- | expr OR2 expr
- { $$ = make_expr(TYPBOOL,EX_OR2,b_expr($1),b_expr($3)); }
- | expr AND2 expr
- { $$ = make_expr(TYPBOOL,EX_AND2,b_expr($1),b_expr($3)); }
- | expr '+' expr
- { $$ = sum_expr($1,$3); }
- | expr '-' expr
- { $$ = make_expr(TYPINT,EX_MINUS,i_expr($1),i_expr($3)); }
- | expr '*' expr
- { $$ = make_expr(TYPINT,EX_TIMES,i_expr($1),i_expr($3)); }
- | expr '/' expr
- { $$ = make_expr(TYPINT,EX_DIVIDE,i_expr($1),i_expr($3)); }
- | expr '%' expr
- { $$ = make_expr(TYPINT,EX_MOD,i_expr($1),i_expr($3)); }
- | expr LSHIFT expr
- { $$ = make_expr(TYPINT,EX_LSHIFT,i_expr($1),i_expr($3)); }
- | expr RSHIFT expr
- { $$ = make_expr(TYPINT,EX_RSHIFT,i_expr($1),i_expr($3)); }
- | NOT expr
- { $$ = make_expr(TYPBOOL,EX_NOT,b_expr($2),0); }
- | COMP expr
- { $$ = make_expr(TYPINT,EX_COMP,i_expr($2),0); }
- | INREG '(' expr ')'
- { $$ = make_expr(TYPINT,EX_INREG,i_expr($3),0); }
- | regvartype
- { $$ = make_expr(TYPINT,EX_CON, $1+1, 0); }
- | REGVAR '(' expr optregvartype ')'
- { $$ = regvar_expr($3,$4); }
- ;
- optregvartype
- : /* empty */
- { $$ = reg_any; }
- | ',' regvartype
- { $$ = $2; }
- ;
- %%
- #include "scan.c"
|