123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125 |
- %{
- #ifndef NORCSID
- static char rcsid[]="$Id$";
- #endif
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- * Author: Hans van Staveren
- */
- #include <stdio.h>
- #include <assert.h>
- #include <em_spec.h>
- #include <em_flag.h>
- #include <em_reg.h>
- #define extern
- #include "booth.h"
- #undef extern
- %}
- %union {
- int yy_int;
- int *yy_intp;
- string yy_string;
- list1 yy_list1;
- list2 yy_list2;
- expr_t yy_expr;
- cost_t yy_cost;
- set_t yy_set;
- ident_p yy_ident;
- char yy_char;
- inst_t yy_instance;
- }
- %type <yy_list1> list1,structlistel
- %type <yy_list2> structlist,structdecl
- %type <yy_expr> expr optexpr
- %type <yy_cost> optcost cost optcommacost
- %type <yy_int> optboolexpr optnocoerc mnem emargno tokargno optprop
- %type <yy_int> optcommabool optstack subreg tokenexpressionno optregvar
- %type <yy_int> tokeninstanceno code stackreplacement optslashnumber
- %type <yy_set> tokenexpression
- %type <yy_instance> tokeninstance
- %type <yy_string> optformat
- %token <yy_string> IDENT TYPENAME
- %token <yy_ident> RIDENT,PIDENT,TIDENT,EIDENT
- %token <yy_string> LSTRING,STRING
- %token <yy_int> NUMBER
- %token <yy_intp> CIDENT
- %token REGISTERHEAD TOKENHEAD EXPRESSIONHEAD CODEHEAD MOVEHEAD TESTHEAD STACKHEAD
- %token REGVAR INREG LOOP POINTER FLOAT
- %token TIMEFAC SIZEFAC FORMAT RETURN
- %token MOVE ERASE ALLOCATE ELLIPS COST REMOVE STACK
- %token SEP SAMESIGN SFIT UFIT ROM DEFINED TOSTRING LOWW HIGHW
- %token NOCC SETCC SAMECC TEST NOCOERC
- %token <yy_char> LCASELETTER
- %start machinespec
- %left OR2
- %left AND2
- %left CMPEQ,CMPNE
- %left CMPLT,CMPLE,CMPGT,CMPGE
- %left RSHIFT,LSHIFT
- %left '+','-'
- %left '*','/','%'
- %nonassoc NOT,COMP,UMINUS
- %nonassoc '$'
- %%
- machinespec
- : rcsid constants registersection tokensection
- { inbetween(); }
- expressionsection codesection movesection testsection stacksection
- ;
- rcsid
- : /* empty */
- | STRING
- { strlookup($1); }
- ;
- constants
- : /* empty */
- | constants CIDENT '=' NUMBER
- { *$2 = $4; }
- | constants SIZEFAC '=' NUMBER optslashnumber
- { cc1 = $4; cc2 = $5; }
- | constants TIMEFAC '=' NUMBER optslashnumber
- { cc3 = $4; cc4 = $5; }
- | constants FORMAT '=' STRING
- { fmt = $4; }
- ;
- optslashnumber
- : /* empty */
- { $$ = 1; }
- | '/' NUMBER
- { $$ = $2; }
- ;
- registersection
- : REGISTERHEAD registerdefs
- ;
- registerdefs
- : /* empty */
- | registerdefs registerdef
- ;
- registerdef
- : IDENT '=' '(' STRING ',' NUMBER list1 ')' optregvar list1 '.'
- { register ident_p ip;
- register list1 l;
- register reginfo r;
- int i;
- r=(reginfo) myalloc(sizeof(struct reginfo));
- r->rname = $1;
- r->rrepr = $4;
- r->rsize = $6;
- if($9>=0 && $7!=0)
- yyerror("No subregisters allowed in regvar");
- for (i=0;i<MAXMEMBERS;i++)
- r->rmembers[i] = 0;
- i=0;
- for (l=$7;l!=0;l=l->l1next) {
- ip=ilookup(l->l1name,LOOKUP);
- if (ip->i_type != IREG)
- yyerror("Bad member of set");
- chktabsiz(i,MAXMEMBERS,"Member of register");
- r->rmembers[i++] = ip->i_i.i_regno;
- }
- maxmembers=max(maxmembers,i);
- r->rregvar=$9;
- if ($9>=0) {
- rvused=1;
- chktabsiz(nregvar[$9],MAXREGVARS,"Regvar");
- rvnumbers[$9][nregvar[$9]++] = nmachregs;
- }
- for(i=0;i<PROPSETSIZE;i++)
- r->rprop[i] = 0;
- ip=ilookup($1,ENTER);
- ip->i_type=IREG;
- ip->i_i.i_regno=nmachregs;
- for (l = $10; l!= 0; l=l->l1next) {
- ip = ilookup(l->l1name,HALFWAY);
- if (ip->i_type) {
- if (ip->i_type != IPRP)
- yyerror("Multiple defined symbol");
- else if(machprops[ip->i_i.i_prpno].propset.set_size != r->rsize)
- yyerror("property has more than 1 size");
- } else {
- chktabsiz(nprops,MAXPROPS,"Property");
- ip->i_type = IPRP;
- ip->i_i.i_prpno = nprops;
- machprops[nprops].propname = ip;
- machprops[nprops++].propset.set_size = r->rsize;
- }
- r->rprop[ip->i_i.i_prpno>>4] |= (1<<(ip->i_i.i_prpno&017));
- }
- chktabsiz(nmachregs,MAXREGS,"Register table");
- machregs[nmachregs++] = r;
- }
- | error '.'
- ;
- optregvar
- : /* nothing */
- { $$ = -1; }
- | REGVAR
- { $$ = reg_any; }
- | REGVAR '(' LOOP ')'
- { $$ = reg_loop; }
- | REGVAR '(' POINTER ')'
- { $$ = reg_pointer; }
- | REGVAR '(' FLOAT ')'
- { $$ = reg_float; }
- ;
- tokensection
- : TOKENHEAD tkdefs
- ;
- tkdefs
- : /* empty */
- | tkdefs tkdef
- ;
- tkdef
- : IDENT '=' structdecl NUMBER optcost optformat
- { register token_p tp;
- register ident_p ip;
- chktabsiz(nmachtokens,MAXTOKENS,"Token table");
- tp = &machtokens[nmachtokens];
- tp->t_name = $1;
- tp->t_struct = $3;
- tp->t_size = $4;
- tp->t_cost = $5;
- ip = ilookup($1,ENTER);
- ip->i_type = ITOK;
- ip->i_i.i_tokno = nmachtokens++;
- maxtokensize=max(maxtokensize,structsize($3));
- setfields(tp,$6);
- }
- | error
- ;
- structdecl
- : '{' structlist '}'
- { $$ = lookstruct($2); }
- ;
- structlist
- : /* empty */
- { $$=0; }
- | structlistel structlist
- { $$=(list2) myalloc(sizeof(struct list2str));
- $$->l2next = $2;
- $$->l2list = $1;
- }
- ;
- structlistel
- : TYPENAME list1 ';'
- { $$=(list1) myalloc(sizeof(struct list1str));
- $$->l1next = $2;
- $$->l1name = $1;
- }
- ;
- optcost : /* empty */
- { $$.c_size = $$.c_time = 0; }
- | COST '=' '(' expr ',' expr ')'
- { MUST2BEINT($4,$6);
- $$.c_size = exp1;
- $$.c_time = exp2;
- }
- ;
- optformat
- : /* empty */
- { $$ = 0; }
- | STRING
- ;
- expressionsection
- : /* empty */
- | EXPRESSIONHEAD tokenexpressions
- ;
- tokenexpressions
- : tokenexpressionline
- | tokenexpressionline tokenexpressions
- ;
- tokenexpressionline
- : IDENT '=' tokenexpression
- {
- { register ident_p ip;
- chktabsiz(nmachsets,MAXSETS,"Expression table");
- machsets[nmachsets] = $3;
- ip=ilookup($1,ENTER);
- ip->i_type = IEXP;
- ip->i_i.i_expno = nmachsets++;
- }
- }
- | error
- ;
- tokenexpression
- : PIDENT
- { $$ = machprops[$1->i_i.i_prpno].propset; }
- | TIDENT
- { register i;
- for(i=0;i<SETSIZE;i++) $$.set_val[i]=0;
- $$.set_val[($1->i_i.i_tokno+nmachregs+1)>>4] |=
- 01<<(($1->i_i.i_tokno+nmachregs+1)&017);
- $$.set_size = machtokens[$1->i_i.i_tokno].t_size;
- }
- | EIDENT
- { $$=machsets[$1->i_i.i_expno]; }
- | tokenexpression '*' tokenexpression
- { register i;
- if (($$.set_size=$1.set_size)==0)
- $$.set_size = $3.set_size;
- for (i=0;i<SETSIZE;i++)
- $$.set_val[i] = $1.set_val[i] & $3.set_val[i];
- }
- | tokenexpression '+' tokenexpression
- { register i;
- if ($1.set_size == -1)
- $$.set_size = $3.set_size;
- else if ($3.set_size == -1)
- $$.set_size = $1.set_size;
- else if ($1.set_size == $3.set_size)
- $$.set_size = $1.set_size;
- else
- $$.set_size = 0;
- for (i=0;i<SETSIZE;i++)
- $$.set_val[i] = $1.set_val[i] | $3.set_val[i];
- }
- | tokenexpression '-' tokenexpression
- { register i;
- if ($1.set_size == -1)
- $$.set_size = $3.set_size;
- else if ($3.set_size == -1)
- $$.set_size = $1.set_size;
- else if ($1.set_size == $3.set_size)
- $$.set_size = $1.set_size;
- else
- $$.set_size = 0;
- for (i=0;i<SETSIZE;i++)
- $$.set_val[i] = $1.set_val[i] & ~ $3.set_val[i];
- }
- | '(' tokenexpression ')'
- { $$ = $2; }
- ;
- codesection
- : CODEHEAD coderules
- ;
- coderules
- : coderule
- | coderules coderule
- ;
- coderule
- : { nallreg=emrepllen=tokrepllen=0; }
- empattern SEP stackpattern SEP code SEP stackreplacement SEP
- emreplacement SEP cost
- { int i;
- if (emrepllen) {
- outbyte(DO_EMREPLACE+(emrepllen<<5));
- for (i=0;i<emrepllen;i++) {
- out(replmnem[i]);
- out(replexpr[i]);
- }
- }
- if ($8==0) {
- outbyte(DO_TOKREPLACE+(tokrepllen<<5));
- for(i=0;i<tokrepllen;i++)
- out(replinst[i]);
- } else {
- static int warncount=0;
- if (!warncount++)
- fprintf(stderr,
- "WARNING: convert to stacksection, will disappear soon");
- outbyte(DO_TOKREPLACE);
- }
- if ($12.c_size!=0 || $12.c_time!=0) {
- outbyte(DO_COST);
- out($12.c_size);
- out($12.c_time);
- }
- outbyte(empatlen==0? DO_RETURN : DO_NEXTEM);
- fprintf(cfile,"\n");
- ncoderules++;
- maxallreg=max(maxallreg,nallreg);
- if (empatlen==0) { /* coercion */
- if (tokrepllen<1 && $8==0)
- yyerror("No replacement in coercion");
- if (tokpatlen>1)
- yyerror("Token pattern too long");
- if ($8!=0) { /* stacking */
- c1_p cp;
- chktabsiz(nc1,MAXC1,"Coerc table 1");
- cp = &c1coercs[nc1++];
- cp->c1_texpno = pattokexp[1];
- cp->c1_prop = -1;
- cp->c1_codep = $6;
- } else if (tokrepllen>1) { /* splitting */
- c2_p cp;
- chktabsiz(nc2,MAXC2,"Coerc table 2");
- cp= &c2coercs[nc2++];
- cp->c2_texpno = pattokexp[1];
- cp->c2_nsplit = tokrepllen;
- maxsplit=max(maxsplit,tokrepllen);
- for (i=0;i<tokrepllen;i++)
- cp->c2_repl[i] = replinst[i];
- cp->c2_codep = $6;
- if (nallreg>0)
- yyerror("No allocates allowed here");
- } else { /* one to one coercion */
- c3_p cp;
- chktabsiz(nc3,MAXC3,"Coerc table 3");
- cp= &c3coercs[nc3++];
- if (tokpatlen)
- cp->c3_texpno = pattokexp[1];
- else
- cp->c3_texpno = 0;
- if (nallreg>1)
- yyerror("Too many allocates in coercion");
- cp->c3_prop = nallreg==0 ? 0 : allreg[0];
- cp->c3_repl = replinst[0];
- cp->c3_codep = $6;
- }
- }
- }
- | error
- ;
- empattern
- : /* empty */
- { empatlen=0; }
- | mnemlist optboolexpr
- { register i;
- empatexpr = $2;
- patbyte(0);
- patshort(prevind);
- prevind = npatbytes - 3;
- maxempatlen = max(empatlen,maxempatlen);
- pat(empatlen);
- for(i=1;i<=empatlen;i++)
- patbyte(patmnem[i]);
- pat(empatexpr);
- rulecount = npatbytes;
- patbyte(1); /* number of different rules with this pattern */
- pat(codebytes); /* first rule */
- }
- | ELLIPS
- { pattern[rulecount]++;
- maxrule= max(maxrule,pattern[rulecount]);
- pat(codebytes);
- }
- ;
- mnemlist
- : mnem
- { empatlen = 1; patmnem[empatlen] = $1; }
- | mnemlist mnem
- { chktabsiz(empatlen+1,MAXEMPATLEN,"EM pattern");
- patmnem[++empatlen] = $2;
- }
- ;
- mnem : IDENT
- { if(strlen($1)!=3 || ($$=mlookup($1))==0)
- yyerror("not an EM-mnemonic");
- }
- ;
- stackpattern
- : optnocoerc tokenexpressionlist optstack
- { register i;
- if (tokpatlen != 0) {
- outbyte(($1 ? ( $3 ? DO_XXMATCH: DO_XMATCH ) : DO_MATCH)+(tokpatlen<<5));
- for(i=1;i<=tokpatlen;i++) {
- out(pattokexp[i]);
- }
- }
- if ($3 && tokpatlen==0 && empatlen==0) {
- outbyte(DO_COERC);
- }
- if ($3 && !$1 && empatlen!=0) {
- outbyte(DO_REMOVE);
- out(allexpno);
- }
- }
- ;
- optnocoerc
- : /* empty */
- { $$ = 0; }
- | NOCOERC ':'
- { $$ = 1; }
- ;
- tokenexpressionlist
- : /* empty */
- { tokpatlen = 0; }
- | tokenexpressionlist tokenexpressionno
- { chktabsiz(tokpatlen+1,MAXPATLEN,"Token pattern");
- pattokexp[++tokpatlen] = $2;
- if (machsets[$2].set_size==0)
- yyerror("Various sized set in tokenpattern");
- }
- ;
- tokenexpressionno
- : tokenexpression
- { $$ = exprlookup($1); }
- ;
- optstack
- : /* empty */
- { $$ = 0; }
- | STACK
- { $$ = 1; }
- ;
- code :
- { $$ = codebytes; cchandled=ccspoiled=0; }
- initcode restcode
- { if (cchandled==0 && ccspoiled!=0) {
- outbyte(DO_ERASE);
- out(ccregexpr);
- }
- }
- ;
- initcode
- : /* empty */
- | initcode remove
- | initcode allocate
- ;
- remove
- : REMOVE '(' tokenexpressionno
- { curtokexp = $3; }
- optcommabool ')'
- { outbyte(DO_REMOVE+ ($5!=0 ? 32 : 0));
- out($3);
- if ($5!=0) out($5);
- }
- | REMOVE '(' expr ')'
- { if ($3.expr_typ != TYPREG)
- yyerror("Expression must be register");
- outbyte(DO_RREMOVE);
- out($3.expr_index);
- }
- ;
- optcommabool
- : /* empty */
- { $$ = 0; }
- | ',' expr
- { MUST1BEBOOL($2);
- $$ = exp1;
- }
- ;
- restcode: /* empty */
- | restcode LSTRING expr
- { outbyte(DO_LOUTPUT);
- out(stringno($2));
- free($2);
- out($3.expr_index);
- ccspoiled++;
- }
- | restcode stringlist
- { int i;
- for(i=0;nstr>0;i++,nstr--) {
- if (i%8==0) outbyte(DO_ROUTPUT+(nstr>7 ? 7 : nstr-1)*32);
- out(strar[i]);
- }
- ccspoiled++;
- }
- | restcode RETURN
- { outbyte(DO_PRETURN); }
- | restcode move
- | restcode erase
- | restcode NOCC
- { outbyte(DO_ERASE);
- out(ccregexpr);
- cchandled++;
- }
- | restcode SAMECC
- { cchandled++; }
- | restcode SETCC '(' tokeninstanceno ')'
- { outbyte(DO_MOVE);
- out(ccinstanceno);
- out($4);
- cchandled++;
- }
- | restcode TEST '(' tokeninstanceno ')'
- { outbyte(DO_MOVE);
- out($4);
- out(ccinstanceno);
- ccspoiled=0;
- }
- ;
- stringlist
- : STRING
- { nstr=1;
- strar[0]=stringno($1);
- free($1);
- }
- | stringlist STRING
- { chktabsiz(nstr,MAXNSTR,"Consecutiv strings");
- strar[nstr++] = stringno($2);
- free($2);
- }
- ;
- move
- : MOVE '(' tokeninstanceno ',' tokeninstanceno ')'
- { outbyte(DO_MOVE);
- out($3);
- out($5);
- }
- ;
- erase
- : ERASE '(' expr ')'
- { outbyte(DO_ERASE);
- out($3.expr_index);
- if($3.expr_typ != TYPREG)
- yyerror("Bad argument of erase");
- }
- ;
- allocate
- : ALLOCATE { dealflag=0; } '(' alloclist ')'
- { if (dealflag)
- outbyte(DO_REALLOCATE);
- }
- ;
- alloclist
- : allocel
- | alloclist optcomma allocel
- ;
- allocel
- : tokeninstanceno /* deallocate */
- { outbyte(DO_DEALLOCATE);
- out($1);
- dealflag++;
- }
- | PIDENT
- { allreg[nallreg++] = $1->i_i.i_prpno;
- outbyte(DO_ALLOCATE);
- out($1->i_i.i_prpno);
- }
- | PIDENT '=' tokeninstanceno
- { allreg[nallreg++] = $1->i_i.i_prpno;
- outbyte(DO_ALLOCATE+32);
- out($1->i_i.i_prpno);
- out($3);
- }
- ;
- stackreplacement
- : /* empty */
- { $$=0; }
- | STACK
- { $$=1; }
- | '{' STACK '}'
- { $$=1; }
- | stackrepllist
- { $$=0; }
- ;
- stackrepllist
- : tokeninstanceno
- { tokrepllen=1; replinst[0] = $1; }
- | stackrepllist tokeninstanceno
- { chktabsiz(tokrepllen+1,MAXPATLEN,"Stack replacement");
- replinst[tokrepllen++] = $2;
- }
- ;
- emreplacement
- : /* empty, normal case */
- | emrepllist
- ;
- emrepllist
- : mnem optexpr
- { emrepllen=1;
- replmnem[0]=$1;
- replexpr[0]=$2.expr_index;
- }
- | emrepllist mnem optexpr
- { chktabsiz(emrepllen+1,MAXEMPATLEN,"EM replacement");
- replmnem[emrepllen]=$2;
- replexpr[emrepllen]=$3.expr_index;
- emrepllen++;
- }
- ;
- cost : /* empty */
- { $$.c_size = $$.c_time = 0;
- }
- | '(' expr ',' expr ')'
- { MUST2BEINT($2,$4);
- $$.c_size = exp1;
- $$.c_time = exp2;
- }
- | cost '+' '%' '[' tokargno ']'
- { $$.c_size = lookup(1,EX_PLUS,$1.c_size,
- lookup(0,EX_COST,$5,0));
- $$.c_time = lookup(1,EX_PLUS,$1.c_time,
- lookup(0,EX_COST,$5,1));
- }
- ;
- movesection
- : MOVEHEAD movedefs
- ;
- movedefs
- : movedef
- | movedefs movedef
- ;
- movedef
- : '(' tokenexpressionno
- { curtokexp = $2; }
- optboolexpr ',' tokenexpressionno
- { curtokexp = $6;
- pattokexp[1] = $2;
- pattokexp[2] = $6;
- tokpatlen=2;
- }
- optboolexpr ',' code optcommacost ')'
- { register move_p mp;
- outbyte(DO_RETURN);
- fprintf(cfile,"\n");
- chktabsiz(nmoves,NMOVES,"Move definition table");
- mp = &machmoves[nmoves++];
- mp->m_set1 = $2;
- mp->m_expr1= $4;
- mp->m_set2 = $6;
- mp->m_expr2= $8;
- mp->m_cindex=$10;
- mp->m_cost = $11;
- }
- | error
- ;
- testsection
- : /* empty */
- | TESTHEAD testdefs
- ;
- testdefs: testdef
- | testdefs testdef
- ;
- testdef : '(' tokenexpressionno
- { curtokexp = $2;
- pattokexp[1] = $2;
- pattokexp[2] = cocosetno;
- tokpatlen=2;
- }
- optboolexpr ',' code optcommacost ')'
- { register move_p mp;
- outbyte(DO_RETURN);
- fprintf(cfile,"\n");
- chktabsiz(nmoves,NMOVES,"Move definition table(tests)");
- mp = &machmoves[nmoves++];
- mp->m_set1 = $2;
- mp->m_expr1 = $4;
- mp->m_set2 = cocosetno;
- mp->m_expr2 = 0;
- mp->m_cindex = $6;
- mp->m_cost = $7;
- }
- ;
- stacksection
- : STACKHEAD stackdefs
- | /* empty */
- ;
- stackdefs
- : stackdef
- | stackdefs stackdef
- ;
- stackdef
- : '(' tokenexpressionno
- { curtokexp = $2;
- pattokexp[1] = $2;
- tokpatlen=1;
- }
- optboolexpr ',' optprop ',' code optcommacost ')'
- { register c1_p cp;
- outbyte(DO_TOKREPLACE);
- outbyte(DO_RETURN);
- fprintf(cfile,"\n");
- chktabsiz(nc1,MAXC1,"Stacking table");
- cp = &c1coercs[nc1++];
- cp->c1_texpno = $2;
- cp->c1_expr = $4;
- cp->c1_prop = $6;
- cp->c1_codep = $8;
- cp->c1_cost = $9;
- }
- ;
- optprop
- : /* empty */
- { $$ = -1; }
- | PIDENT
- { $$ = $1->i_i.i_prpno; }
- ;
- optcommacost
- : /* empty */
- { $$.c_size = 0; $$.c_time = 0;}
- | ',' cost
- { $$ = $2; }
- ;
- list1 : /* empty */
- { $$ = 0; }
- | optcomma IDENT list1
- { $$=(list1) myalloc(sizeof(struct list1str));
- $$->l1next = $3;
- $$->l1name = $2;
- }
- ;
- optcomma: /* nothing */
- | ','
- ;
- emargno : NUMBER
- { if ($1<1 || $1>empatlen)
- yyerror("Number after $ out of range");
- $$ = $1;
- }
- ;
- tokargno
- : NUMBER
- { if ($1<1 || $1>tokpatlen)
- yyerror("Number within %[] out of range");
- $$ = $1;
- }
- ;
- expr : '$' emargno
- { $$.expr_index = lookup(0,EX_ARG,$2,0); $$.expr_typ = argtyp(patmnem[$2]);
- }
- | NUMBER
- { $$.expr_index = lookup(0,EX_CON,(int)($1&0177777),(int)($1>>16));
- $$.expr_typ = TYPINT;
- }
- | STRING
- { $$.expr_index = lookup(0,EX_STRING,strlookup($1),0);
- $$.expr_typ = TYPSTR;
- }
- | RIDENT
- { $$.expr_index = lookup(0,EX_REG,$1->i_i.i_regno,0);
- $$.expr_typ = TYPREG;
- }
- | '%' '[' tokargno '.' IDENT ']'
- { $$.expr_index = lookup(0,EX_TOKFIELD,$3,
- findstructel(pattokexp[$3],$5,&$$.expr_typ));
- }
- | '%' '[' tokargno subreg ']'
- { chkregexp(pattokexp[$3]);
- $$.expr_index = lookup(0,EX_SUBREG,$3,$4);
- $$.expr_typ = TYPREG;
- }
- | '%' '[' LCASELETTER subreg ']'
- { if ($3 >= 'a'+nallreg)
- yyerror("Bad letter in %[x] construct");
- $$.expr_index = lookup(0,EX_ALLREG,$3-'a'+1,$4);
- $$.expr_typ = TYPREG;
- }
- | '%' '[' IDENT ']'
- { $$.expr_index = lookup(0,EX_TOKFIELD,0,
- findstructel(curtokexp,$3,&$$.expr_typ));
- }
- | TOSTRING '(' expr ')'
- { MUST1BEINT($3);
- $$.expr_index = lookup(0,EX_TOSTRING,exp1,0);
- $$.expr_typ = TYPSTR;
- }
- | DEFINED '(' expr ')'
- { $$.expr_index = lookup(0,EX_DEFINED,$3.expr_index,0);
- $$.expr_typ = TYPBOOL;
- }
- | SAMESIGN '(' expr ',' expr ')'
- { MUST2BEINT($3,$5);
- $$.expr_index = lookup(1,EX_SAMESIGN,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | SFIT '(' expr ',' expr ')'
- { MUST2BEINT($3,$5);
- $$.expr_index = lookup(0,EX_SFIT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | UFIT '(' expr ',' expr ')'
- { MUST2BEINT($3,$5);
- $$.expr_index = lookup(0,EX_UFIT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | ROM '(' emargno ',' NUMBER ')'
- { if ($5<1 || $5>3)
- yyerror("Second argument of rom must be >=1 and <=3");
- $$.expr_index = lookup(0,EX_ROM,$3-1,$5-1);
- $$.expr_typ = TYPINT;
- }
- | LOWW '(' emargno ')'
- {
- $$.expr_index = lookup(0,EX_LOWW,$3-1,0);
- $$.expr_typ = TYPINT;
- }
- | HIGHW '(' emargno ')'
- {
- $$.expr_index = lookup(0,EX_HIGHW,$3-1,0);
- $$.expr_typ = TYPINT;
- }
- | '(' expr ')'
- { $$ = $2; }
- | expr CMPEQ expr
- { switch(commontype($1,$3)) {
- case TYPINT:
- $$.expr_index = lookup(1,EX_NCPEQ,$1.expr_index,$3.expr_index);
- break;
- case TYPSTR:
- $$.expr_index = lookup(1,EX_SCPEQ,$1.expr_index,$3.expr_index);
- break;
- case TYPREG:
- $$.expr_index = lookup(1,EX_RCPEQ,$1.expr_index,$3.expr_index);
- break;
- }
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPNE expr
- { switch(commontype($1,$3)) {
- case TYPINT:
- $$.expr_index = lookup(1,EX_NCPNE,$1.expr_index,$3.expr_index);
- break;
- case TYPSTR:
- $$.expr_index = lookup(1,EX_SCPNE,$1.expr_index,$3.expr_index);
- break;
- case TYPREG:
- $$.expr_index = lookup(1,EX_RCPNE,$1.expr_index,$3.expr_index);
- break;
- }
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPGT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPGT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPGE expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPGE,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPLT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPLT,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr CMPLE expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_NCPLE,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr OR2 expr
- { MUST2BEBOOL($1,$3);
- $$.expr_index = lookup(0,EX_OR2,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr AND2 expr
- { MUST2BEBOOL($1,$3);
- $$.expr_index = lookup(0,EX_AND2,exp1,exp2);
- $$.expr_typ = TYPBOOL;
- }
- | expr '+' expr
- { switch(commontype($1,$3)) {
- case TYPINT:
- $$.expr_index = lookup(1,EX_PLUS,$1.expr_index,$3.expr_index);
- break;
- case TYPSTR:
- $$.expr_index = lookup(0,EX_CAT,$1.expr_index,$3.expr_index);
- break;
- default:
- yyerror("Bad types");
- }
- $$.expr_typ = $1.expr_typ;
- }
- | expr '-' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_MINUS,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr '*' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(1,EX_TIMES,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr '/' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_DIVIDE,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr '%' expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_MOD,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr LSHIFT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_LSHIFT,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | expr RSHIFT expr
- { MUST2BEINT($1,$3);
- $$.expr_index = lookup(0,EX_RSHIFT,exp1,exp2);
- $$.expr_typ = TYPINT;
- }
- | NOT expr
- { MUST1BEBOOL($2);
- $$.expr_index = lookup(0,EX_NOT,exp1,0);
- $$.expr_typ = TYPBOOL;
- }
- | COMP expr
- { MUST1BEINT($2);
- $$.expr_index = lookup(0,EX_COMP,exp1,0);
- $$.expr_typ = TYPINT;
- }
- | INREG '(' expr ')'
- { MUST1BEINT($3);
- $$.expr_index = lookup(0,EX_INREG,exp1,0);
- $$.expr_typ = TYPINT;
- }
- | REGVAR '(' expr ')'
- { MUST1BEINT($3);
- $$.expr_index = lookup(0,EX_REGVAR,exp1,0);
- $$.expr_typ = TYPREG;
- }
- /*
- | '-' expr %prec UMINUS
- { MUST1BEINT($2);
- $$.expr_index = lookup(0,EX_UMINUS,exp1,0);
- $$.expr_typ = TYPINT;
- }
- */
- ;
- subreg : /* empty */
- { $$=0; }
- | '.' NUMBER
- { $$=$2; }
- ;
- optboolexpr
- : /* empty */
- { $$ = 0; }
- | expr
- { MUST1BEBOOL($1);
- $$=exp1;
- }
- ;
- optexpr
- : /* empty */
- { $$.expr_typ=0;
- $$.expr_index=0;
- }
- | expr
- ;
- tokeninstanceno
- : tokeninstance
- { $$ = instno($1); }
- ;
- tokeninstance
- : '%' '[' tokargno subreg ']'
- { register i;
- if ($4!=0)
- chkregexp(pattokexp[$3]);
- $$.in_which = IN_COPY;
- $$.in_info[0] = $3;
- $$.in_info[1] = $4;
- for (i=2;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | '%' '[' tokargno '.' IDENT ']'
- { int typ;
- register i;
- $$.in_which = IN_COPY;
- $$.in_info[0] = $3;
- $$.in_info[1] = findstructel(pattokexp[$3],$5,&typ);
- if (typ != TYPREG)
- yyerror("Must be register");
- for (i=2;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | RIDENT
- { register i;
- $$.in_which = IN_RIDENT;
- $$.in_info[0] = $1->i_i.i_regno;
- for (i=1;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | REGVAR '(' expr ')'
- { register i;
- MUST1BEINT($3);
- $$.in_which = IN_REGVAR;
- $$.in_info[0] = exp1;
- for (i=1;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | '%' '[' LCASELETTER subreg ']'
- { register i;
- if ($3 >= 'a'+nallreg)
- yyerror("Bad letter in %[x] construct");
- $$.in_which = IN_ALLOC;
- $$.in_info[0] = $3-'a';
- $$.in_info[1] = $4;
- for (i=2;i<TOKENSIZE;i++)
- $$.in_info[i] = 0;
- }
- | '{' TIDENT attlist '}'
- { register i;
- $$.in_which = IN_DESCR;
- $$.in_info[0] = $2->i_i.i_tokno;
- for(i=0;i<narexp;i++) {
- if (arexp[i].expr_typ !=
- machtokens[$2->i_i.i_tokno].t_fields[i].t_type)
- yyerror("Attribute %d has wrong type",i+1);
- $$.in_info[i+1] = arexp[i].expr_index;
- }
- for (i=narexp+1;i<TOKENSIZE;i++) {
- if (machtokens[$2->i_i.i_tokno].t_fields[i-1].t_type!=0)
- yyerror("Too few attributes");
- $$.in_info[i] = 0;
- }
- }
- ;
- attlist
- : /* empty */
- { narexp = 0; }
- | attlist ',' expr
- { arexp[narexp++] = $3; }
- ;
- %%
|