1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- %{
- #ifndef NORCSID
- static char rcsid[]= "$Id$";
- #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 att_type;
- int patindex[MAXPATTERNS];
- extern set_t l_sets[];
- 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 maxrule=0;
- int in_em_repl=0; /* set when in EM replacement part */
- struct varinfo *defcost;
- int Xstackflag=0; /* set in coercions, moves, and tests. %1 means something
- different then.
- */
- struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
- struct varinfo *gen_label(), *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(),percident_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 TOPELTSIZE FALLTHROUGH LABELDEF
- %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 ISROM
- %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 att_list_el_list att_ident 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
- %type <yy_expr> expr regvarexpr
- %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 '|'
- %left '^'
- %left '&'
- %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; while ($$->vi_next) $$ = $$->vi_next;
- $$->vi_next = $2; $$ = $1;
- }
- ;
- att_list_el
- : att_list_el_type
- { att_type = $1; }
- att_list_el_list
- ';'
- { $$ = $3; }
- ;
- att_list_el_list
- : att_ident
- | att_ident ',' att_list_el_list
- { $1->vi_next = $3; $$ = $1; }
- ;
- att_ident
- : IDENT
- { NEW($$, struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = att_type;
- $$->vi_str[0] = $1;
- }
- ;
- 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
- { Xstackflag = 1;
- cursetno = $3;
- }
- optexpr
- { Xstackflag = 0;
- cursetno = -1;
- }
- TO tokenset_no
- { cursetno = $8;
- tokpatlen=2;
- tokpatset[0] = $3;
- tokpatset[1] = $8;
- tokpatro[0] = 1;
- Xstackflag = 1;
- }
- optexpr
- { Xstackflag = 0;
- cursetno = -1;
- }
- GEN genlist
- { tokpatlen=0;
- tokpatro[0]=0;
- n_move($3,$5,$8,$10,$13);
- freevi($13);
- }
- | error
- ;
- /* Now the test part */
- tests
- : TESTS
- { Xstackflag = 1; }
- testdeflist
- { Xstackflag = 0; }
- | /* 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);
- cursetno = -1;
- }
- | error
- ;
-
- /* Now the stacks */
- stacks
- : STACKINGRULES
- { Xstackflag = 1; }
- stackdeflist
- { Xstackflag = 0; }
- ;
- 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);
- cursetno = -1;
- }
- ;
- optuses
- : /* empty */
- { $$ = -1; nallreg=0;}
- | USES propno
- { $$ = $2; nallreg = 1; allreg[0] = $2; }
- ;
- /* Now the one-to-one coercion rules */
- coercs
- : COERCIONS
- { Xstackflag = 1; }
- coercdeflist
- { Xstackflag = 0; }
- ;
- coercdeflist
- : coercdeflist_el
- | coercdeflist coercdeflist_el
- ;
- coercdeflist_el
- : FROM
- {startline = lineno; tokpatlen=0; inithall();}
- STACK allocates generates YIELDS tokeninstance
- { checkhall();
- n_coerc(0,0,$4,$5,(struct varinfo *) 0,$7);
- freevi($4);
- freevi($5);
- }
- | 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);
- cursetno = -1;
- }
- ;
- /* 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 '(' stringlist ')'
- { register symbol *sy_p;
- saferulefound=1;
- sy_p=lookup($2,symproc,mustexist);
- callproc=sy_p->sy_value.syv_procoff;
- free($2);
- if (nprocargs > maxprocargs) maxprocargs = nprocargs;
- }
- ;
- stringlist
- : STRING
- { nprocargs = 1; procarg[0] = strlookup($1); free($1); }
- | stringlist ',' STRING
- { NEXT(nprocargs, MAXPROCARG, "Procedure argument list");
- procarg[nprocargs-1] = strlookup($3); free($3);
- }
- ;
- onepattern
- : { inithall(); startline=lineno;
- tokpatlen=0; optexact=0; optstack=0;
- }
- kills allocates generates yields leaving
- {
- 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
- { if (tokpatlen > maxtokpatlen) maxtokpatlen = tokpatlen; }
- ;
- 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);
- if (l_sets[$2].set_size == 0) {
- error("Tokenset is empty or has elements with different sizes");
- }
- }
- ;
- kills
- : /* empty */
- { $$ = 0; }
- | KILLS kill_list
- { $$ = $2;
- }
- ;
- 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;
- cursetno = -1;
- }
- | regvarexpr
- { NEW($$,struct varinfo);
- $$->vi_next = 0;
- $$->vi_int[0] = -($1.ex_index + 1);
- $$->vi_int[1] = 0;
- }
- ;
- 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);}
- | LABELDEF emarg
- { $$ = gen_label($2-1); use_tes++; }
- | 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 { tokrepllen = 0; } yieldlist
- { $$ = $3; if (tokrepllen > maxtokrepllen) maxtokrepllen = tokrepllen; }
- ;
- yieldlist
- : /* empty */
- { $$ = 0; }
- | tokeninstance yieldlist
- { checkstacking($1.in_set);
- NEW($$,struct varinfo);
- $$->vi_next = $2;
- $$->vi_int[0] = $1.in_index;
- tokrepllen++;
- }
- ;
- leaving
- : /* empty */
- { $$ = 0; }
- | LEAVING {emhere=1; in_em_repl=1; emrepllen = 0; } leavelist
- { emhere=0; in_em_repl=0; $$ = $3;
- if (emrepllen > maxemrepllen) maxemrepllen = emrepllen;
- }
- ;
- 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;
- emrepllen++;
- }
- ;
- 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); }
- | PERC_IDENT
- { if (cursetno < 0) {
- error("%%<ident> not allowed here");
- }
- $$ = percident_iocc($1);
- free($1);
- }
- | '{' 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
- { $$ = $1;
- if (in_em_repl)
- error("No token references allowed in EM replacement part");
- if ($1<1 || $1>tokpatlen) {
- error("Only %d tokens in stackpattern",tokpatlen);
- $$ =1;
- }
- if (Xstackflag) $$ = 0;
- }
- ;
- 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
- { if (cursetno < 0) {
- error("%%<ident> not allowed here");
- }
- $$ = 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)); }
- | TOPELTSIZE '(' emarg ')'
- { $$ = make_expr(TYPINT,EX_TOPELTSIZE,$3-1,0); }
- | FALLTHROUGH '(' emarg ')'
- { $$ = make_expr(TYPBOOL,EX_FALLTHROUGH,$3-1,0); }
- | 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); }
- | ISROM '(' emarg ')'
- { $$ = make_expr(TYPBOOL,EX_ISROM,$3-1,0); }
- | LOWW '(' emarg ')'
- { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
- | HIGHW '(' emarg ')'
- { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
- /* Excluded, because it causes a shift-reduce conflict
- (problems with a tokenset_no followed by an optexpr)
- | '-' expr %prec UMINUS
- { $$ = make_expr(TYPINT,EX_CON, 0, 0);
- $$ = make_expr(TYPINT,EX_MINUS,i_expr($$),i_expr($2));
- }
- */
- | '(' 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
- { $$ = make_expr(TYPINT,EX_OR,i_expr($1),i_expr($3)); }
- | expr '^' expr
- { $$ = make_expr(TYPINT,EX_XOR,i_expr($1),i_expr($3)); }
- | expr '&' expr
- { $$ = make_expr(TYPINT,EX_AND,i_expr($1),i_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); }
- | regvarexpr
- ;
- regvarexpr
- : REGVAR '(' expr optregvartype ')'
- { $$ = regvar_expr($3,$4); }
- ;
- optregvartype
- : /* empty */
- { $$ = reg_any; }
- | ',' regvartype
- { $$ = $2; }
- ;
- %%
- #include "scan.c"
|