From 2014f2854c595042fda41db15469e0b95cfa354c Mon Sep 17 00:00:00 2001 From: sater Date: Fri, 18 May 1984 19:51:06 +0000 Subject: [PATCH] Initial revision --- util/cgg/Makefile | 23 + util/cgg/bootgram.y | 2297 +++++++++++++++++++++++++++++++++++++++++++ util/cgg/bootlex.l | 185 ++++ 3 files changed, 2505 insertions(+) create mode 100644 util/cgg/Makefile create mode 100644 util/cgg/bootgram.y create mode 100644 util/cgg/bootlex.l diff --git a/util/cgg/Makefile b/util/cgg/Makefile new file mode 100644 index 000000000..1d5ce4a06 --- /dev/null +++ b/util/cgg/Makefile @@ -0,0 +1,23 @@ +PREFLAGS=-I../../h +CFLAGS=$(PREFLAGS) +LDFLAGS=-i +LINTOPTS=-hbxac $(PREFLAGS) +LIBS=../../lib/em_data.a +# LEXLIB is system dependent, try -ll or -lln first +LEXLIB=-lln + +cgg: bootgram.o + cc $(LDFLAGS) bootgram.o $(LIBS) $(LEXLIB) -o cgg + +install: cgg + cp cgg ../../lib/cgg + +cmp: cgg + cmp cgg ../../lib/cgg + +lint: bootgram.c + lint $(LINTOPTS) bootgram.c +clean: + rm -f bootgram.o bootgram.c bootlex.c cgg +bootgram.o: bootlex.c +bootgram.o: ../../h/cg_pattern.h diff --git a/util/cgg/bootgram.y b/util/cgg/bootgram.y new file mode 100644 index 000000000..87d028b7a --- /dev/null +++ b/util/cgg/bootgram.y @@ -0,0 +1,2297 @@ +%{ + +/* + * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. + * + * This product is part of the Amsterdam Compiler Kit. + * + * Permission to use, sell, duplicate or disclose this software must be + * obtained in writing. Requests for such permissions may be sent to + * + * Dr. Andrew S. Tanenbaum + * Wiskundig Seminarium + * Vrije Universiteit + * Postbox 7161 + * 1007 MC Amsterdam + * The Netherlands + * + * Author: Hans van Staveren + */ + +/* Tunable constants */ + +#define MAXALLREG 5 /* Maximum number of allocates per rule */ +#define MAXREGS 32 /* Total number of registers */ +#define MAXREGVARS 8 /* Maximum regvars per type */ +#define MAXPROPS 16 /* Total number of register properties */ +#define MAXTOKENS 32 /* Different kind of tokens */ +#define MAXSETS 80 /* Number of tokenexpressions definable */ +#define TOKENSIZE 5 /* Maximum number of fields in token struct */ +#define MAXINSTANCE 120 /* Maximum number of different tokeninstances */ +#define MAXSTRINGS 400 /* Maximum number of different codestrings */ +#define MAXPATTERN 6000 /* Maximum number of bytes in pattern[] */ +#define MAXNODES 350 /* Maximum number of expression nodes */ +#define MAXMEMBERS 2 /* Maximum number of subregisters per reg */ +#define NMOVES 30 /* Maximum number of move definitions */ +#define MAXC1 20 /* Maximum of coercions type 1 */ +#define MAXC2 20 /* Maximum of coercions type 2 */ +#define MAXC3 20 /* Maximum of coercions type 3 */ +#define MAXSPLIT 4 /* Maximum degree of split */ +#define MAXNSTR 40 /* Maximum consecutive strings in coderule */ + +/* Derived constants */ + +#define SETSIZE ((MAXREGS+1+MAXTOKENS+15)>>4) +#define PROPSETSIZE ((MAXPROPS+15)>>4) + +#define BMASK 0377 +#define BSHIFT 8 + +#define TRUE 1 +#define FALSE 0 + +#define MAXPATLEN 7 /* Maximum length of em- or tokenpatterns */ + +typedef char byte; +typedef char * string; + +#include +#include +#include +#include +#include +#include +#include + +typedef struct list1str { + struct list1str *l1next; + string l1name; +} *list1; +typedef struct list2str { + struct list2str *l2next; + list1 l2list; +} *list2; +typedef struct list3str { + struct list3str *l3next; + list2 l3list; +} *list3; + +typedef struct reginfo { + string rname; + string rrepr; + int rsize; + int rmembers[MAXMEMBERS]; + int rregvar; + short rprop[PROPSETSIZE]; +} *reginfo; + +typedef struct tokeninfo { + string t_name; + list2 t_struct; + struct { + int t_type; + string t_sname; + } t_fields[TOKENSIZE-1]; + int t_size; + cost_t t_cost; + int t_format; +} token_t,*token_p; + +typedef struct ident { + struct ident *i_next; + string i_name; + int i_type; +# define IREG 1 +# define IPRP 2 +# define ITOK 3 +# define IEXP 4 + union { + int i_regno; + int i_prpno; + int i_tokno; + int i_expno; + } i_i; +} ident_t,*ident_p; + +#define ITABSIZE 32 +ident_p identtab[ITABSIZE]; + +#define LOOKUP 0 +#define HALFWAY 1 +#define ENTER 2 +#define JUSTLOOKING 3 + + +typedef struct expr { + int expr_typ; +# define TYPINT 1 +# define TYPREG 2 +# define TYPSTR 3 +# define TYPBOOL 4 + int expr_index; +} expr_t,*expr_p; + +unsigned cc1=1,cc2=1,cc3=1,cc4=1; + +node_t nodes[MAXNODES]; +node_p lastnode=nodes+1; + +string codestrings[MAXSTRINGS]; +int ncodestrings; + +int strar[MAXNSTR]; +int nstr; + +int pathash[256]; + +reginfo machregs[MAXREGS]; +char stregclass[MAXREGS]; +int nmachregs=1; +int nregclasses=1; +int maxmembers; +struct { + ident_p propname; + set_t propset; +} machprops[MAXPROPS]; +int nprops=0; +token_t machtokens[MAXTOKENS]; +int nmachtokens=1; +set_t machsets[MAXSETS]; +int nmachsets=0; +int patmnem[MAXPATLEN]; +int empatlen; +int maxempatlen; +int empatexpr; +int maxrule=1; +int pattokexp[MAXPATLEN]; +int tokpatlen; +int lookident=0; /* lexical analyzer flag */ +list3 structpool=0; +int nallreg; +int allreg[MAXALLREG]; +int maxallreg; +int lino=0; +int nerrors=0; +int curtokexp; +expr_t arexp[TOKENSIZE]; +int narexp; +inst_t arinstance[MAXINSTANCE]; +int narinstance=1; +move_t machmoves[NMOVES]; +int nmoves=0; +byte pattern[MAXPATTERN]; +int npatbytes=0; +int prevind; +int rulecount; /* Temporary index for ... construct */ +int ncoderules=0; +int codebytes=0; +FILE *cfile; +FILE *hfile; +int maxtokensize=0; +int dealflag; +int emrepllen; +int replmnem[MAXPATLEN]; +int tokrepllen; +int replinst[MAXPATLEN]; +int replexpr[MAXPATLEN]; +c1_t c1coercs[MAXC1]; +c2_t c2coercs[MAXC2]; +c3_t c3coercs[MAXC3]; +int nc1=0,nc2=0,nc3=0; +int maxsplit=0; +int wsize= -1; +int psize= -1; +int bsize= -1; +char *fmt=0; + +int cchandled; +int ccspoiled; +int ccregexpr; +int ccinstanceno; +int cocopropno; +int cocosetno; +int allexpno; + +int rvused; /* regvars used */ +int nregvar[4]; /* # of register variables of all kinds */ +int rvnumbers[4][MAXREGVARS]; /* The register numbers */ + +#define chktabsiz(size,maxsize,which) if(size>=maxsize) tabovf(which) + +#define MUST1BEINT(e) int exp1=e.expr_index;tstint(e) +#define MUST2BEINT(e1,e2) int exp1=e1.expr_index,exp2=e2.expr_index;tstint(e1);tstint(e2) +#define MUST1BEBOOL(e) int exp1=e.expr_index;tstbool(e) +#define MUST2BEBOOL(e1,e2) int exp1=e1.expr_index,exp2=e2.expr_index;tstbool(e1);tstbool(e2) + +%} + +%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 list1,structlistel +%type structlist,structdecl +%type expr optexpr +%type optcost cost optcommacost +%type optboolexpr optnocoerc mnem emargno tokargno optprop +%type optcommabool optstack subreg tokenexpressionno optregvar +%type tokeninstanceno code stackreplacement optslashnumber +%type tokenexpression +%type tokeninstance +%type optformat +%token IDENT TYPENAME +%token RIDENT,PIDENT,TIDENT,EIDENT +%token LSTRING,STRING +%token NUMBER +%token 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 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 + : constants registersection tokensection + { inbetween(); } + expressionsection codesection movesection testsection stacksection + ; + +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;irmembers[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;irprop[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;ii_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;i1) + 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;ic2_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,MAXPATLEN,"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,MAXPATLEN,"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;ii_i.i_regno; + for (i=1;i= 'a'+nallreg) + yyerror("Bad letter in %[x] construct"); + $$.in_which = IN_ALLOC; + $$.in_info[0] = $3-'a'; + $$.in_info[1] = $4; + for (i=2;ii_i.i_tokno; + for(i=0;ii_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;ii_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; } + ; + +%% + +char * myalloc(n) { + register char *p; + + p= (char*) malloc(n); + if (p==0) { + yyerror("Out of core"); + exit(1); + } + return(p); +} + +tstint(e) expr_t e; { + + if(e.expr_typ != TYPINT) + yyerror("Must be integer expression"); +} + +tstbool(e) expr_t e; { + + if(e.expr_typ != TYPBOOL) + yyerror("Must be boolean expression"); +} + +structsize(s) register list2 s; { + register list1 l; + register sum; + + sum = 0; + while ( s != 0 ) { + l = s->l2list->l1next; + while ( l != 0 ) { + sum++; + l = l->l1next; + } + s = s->l2next; + } + return(sum); +} + +list2 lookstruct(ll) list2 ll; { + list3 l3; + list2 l21,l22; + list1 l11,l12; + + for (l3=structpool;l3 != 0;l3=l3->l3next) { + for (l21=l3->l3list,l22=ll;l21!=0 && l22!=0; + l21=l21->l2next,l22=l22->l2next) { + for(l11=l21->l2list,l12=l22->l2list; + l11!=0 && l12!=0 && strcmp(l11->l1name,l12->l1name)==0; + l11=l11->l1next,l12=l12->l1next) + ; + if (l11!=0 || l12!=0) + goto contin; + } + if(l21==0 && l22==0) + return(l3->l3list); + contin:; + } + l3 = (list3) myalloc(sizeof(struct list3str)); + l3->l3next=structpool; + l3->l3list=ll; + structpool=l3; + return(ll); +} + +instno(inst) inst_t inst; { + register i,j; + + for(i=1;itokpatlen) + yyerror("Number within %[] out of range"); + if (*s == ']') { + s++; + *p++ = PR_TOK; + *p++ = num; + } else if (*s++ != '.') + yyerror("Bad character following %%[digit in codestring"); + else { + char field[256]; + register char *f=field; + int type,offset; + + while( *s != ']' && *s != 0) + *f++ = *s++; + *f++ = 0; + if (*s != ']') + yyerror("Unterminated %[] construction in codestring"); + else + s++; + if (isdigit(field[0])) { + chkregexp(pattokexp[num]); + *p++ = PR_SUBREG; + *p++ = num; + *p++ = atoi(field); + } else { + offset = findstructel(pattokexp[num],field,&type); + *p++ = PR_TOKFLD; + *p++ = num; + *p++ = offset; + } + } + } else if (*s >= 'a' && *s < 'a'+nallreg) { + int reg,subreg; + reg = *s++ -'a'+1; + if(*s == ']') + subreg = 255; + else { + if (*s != '.') + yyerror("Bad character following %%[x in codestring"); + s++; + if(!isdigit(*s)) + yyerror("Bad character following %%[x. in codestring"); + subreg = *s - '0'; + s++; + if(*s != ']') + yyerror("Bad character following %%[x.y in codestring"); + } + s++; + *p++ = PR_ALLREG; + *p++ = reg; + *p++ = subreg; + } else + yyerror("Bad character following %%[ in codestring"); + } + *p++ = 0; + return(strlookup(buf)); +} + +tabovf(tablename) string tablename; { + char buf[256]; + + sprintf(buf,"%s overflow",tablename); + yyerror(buf); + exit(-1); +} + +main(argc,argv) char *argv[]; { + + if (argc!=1) { + fprintf(stderr,"%s is a filter, don't use arguments\n",argv[0]); + exit(-1); + } + inithash(); + initio(); + inittables(); + yyparse(); + if (nerrors==0) { + compueq(); + hashpatterns(); + finishio(); + verbose(); + } + debug(); + exit(nerrors); +} + +lookup(comm,operator,lnode,rnode) { + register node_p p; + + for (p=nodes+1;pex_operator != operator) + continue; + if (!(p->ex_lnode == lnode && p->ex_rnode == rnode || + comm && p->ex_lnode == rnode && p->ex_rnode == lnode)) + continue; + return(p-nodes); + } + if (lastnode >= &nodes[MAXNODES]) + yyerror("node table overflow"); + lastnode++; + p->ex_operator = operator; + p->ex_lnode = lnode; + p->ex_rnode = rnode; + return(p-nodes); +} + +compueq() { + register i,j; + + for (i=1;i>4]; + int member; + + rp1 = machregs[r1]; rp2 = machregs[r2]; + for (i=0;i<((nprops+15)>>4);i++) + if (rp1->rprop[i] != rp2->rprop[i]) + return(0); + for (i=0;i<((MAXREGS+15)>>4);i++) + regbits[i] = 0; + for (i=0;irmembers[i]) + regbits[member>>4] |= (1<<(member&017)); + } + for (i=0;irmembers[i]; + if (regbits[member>>4]&(1<<(member&017))) + return(0); + } + return(1); +} + +unsigned hash(name) register string name; { + register unsigned sum; + register i; + + for (sum=i=0;*name;i+=3) + sum ^= (*name++)<<(i&07); + return(sum); +} + +ident_p ilookup(name,enterf) string name; int enterf; { + register ident_p p,*pp; + + pp = &identtab[hash(name)%ITABSIZE]; + while (*pp != 0) { + if (strcmp((*pp)->i_name,name)==0) + if (enterf != ENTER) + return(*pp); + else + yyerror("Multiply defined symbol"); + pp = &(*pp)->i_next; + } + if (enterf == LOOKUP) + yyerror("Undefined symbol"); + if (enterf == JUSTLOOKING) + return(0); + p = *pp = (ident_p) myalloc(sizeof(ident_t)); + p->i_name = name; + p->i_next = 0; + p->i_type = 0; + return(p); +} + +initio() { + + if ((cfile=fopen("tables.c","w"))==NULL) { + fprintf(stderr,"Can't create tables.c\n"); + exit(-1); + } + if ((hfile=fopen("tables.h","w"))==NULL) { + fprintf(stderr,"Can't create tables.h\n"); + exit(-1); + } + fprintf(cfile,"#include \"param.h\"\n"); + fprintf(cfile,"#include \"tables.h\"\n"); + fprintf(cfile,"#include \"types.h\"\n"); + fprintf(cfile,"#include \n"); + fprintf(cfile,"#include \"data.h\"\n"); + fprintf(cfile,"\nbyte coderules[] = {\n"); + patbyte(0); +} + +exprlookup(sett) set_t sett; { + register i,j,ok; + + for(i=0;irname = "cc reg"; + r->rrepr = "CC"; + r->rsize = -1; + r->rregvar= -1; + for(i=0;irmembers[i] = 0; + for(i=0;irprop[i] = 0; + r->rprop[cocopropno>>4] |= (1<<(cocopropno&017)); + chktabsiz(nmachregs,MAXREGS,"Register table"); + machregs[nmachregs++] = r; + inst.in_which = IN_RIDENT; + inst.in_info[0] = nmachregs-1; + for(i=1;i>4] |= (01<<(nmachregs&017)); + cocosetno=exprlookup(sett); +} + +outregs() { + register i,j,k; + static short rset[(MAXREGS+15)>>4]; + int t,ready; + + fprintf(cfile,"char stregclass[] = {\n"); + for (i=0;irrepr), + machregs[i]->rsize); + if (maxmembers!=0) { + fprintf(cfile,",{"); + for(j=0;jrmembers[j]); + /* now compute and print set of registers + * that clashes with this register. + * A register clashes with al its children (and theirs) + * and with all their parents. + */ + for (j=0;j<((MAXREGS+15)>>4);j++) + rset[j]=0; + rset[i>>4] |= (1<<(i&017)); + do { + ready=1; + for (j=1;j>4]&(1<<(j&017))) + for (k=0;krmembers[k])!=0) { + if ((rset[t>>4]&(1<<(t&017)))==0) + ready=0; + rset[t>>4] |= (1<<(t&017)); + } + } while (!ready); + do { + ready=1; + for (j=1;jrmembers[k])!=0) + if (rset[t>>4]&(1<<(t&017))) { + if (rset[j>>4]&(1<<(j&017))==0) + ready=0; + rset[j>>4] |= (1<<(j&017)); + } + } while (!ready); + fprintf(cfile,"},{"); + for (j=0;j<((nmachregs+15)>>4);j++) + fprintf(cfile,"%d,",rset[j]); + fprintf(cfile,"}"); + } + if (machregs[i]->rregvar>=0) + fprintf(cfile,",1"); + fprintf(cfile,"},\n"); + } + fprintf(cfile,"};\n\n"); +} + +finishio() { + register i; + register node_p np; + int j; + int setsize; + register move_p mp; + + fprintf(cfile,"};\n\n"); + if (wsize>0) + fprintf(hfile,"#define EM_WSIZE %d\n",wsize); + else + yyerror("Wordsize undefined"); + if (psize>0) + fprintf(hfile,"#define EM_PSIZE %d\n",psize); + else + yyerror("Pointersize undefined"); + if (bsize>=0) + fprintf(hfile,"#define EM_BSIZE %d\n",bsize); + else + fprintf(hfile,"extern int EM_BSIZE;\n"); + if (fmt!=0) + fprintf(hfile,"#define WRD_FMT \"%s\"\n",fmt); + fprintf(hfile,"#define MAXALLREG %d\n",maxallreg); + setsize = (nmachregs+1 + nmachtokens + 15)>>4; + fprintf(hfile,"#define SETSIZE %d\n",setsize); + fprintf(hfile,"#define NPROPS %d\n",nprops); + fprintf(hfile,"#define NREGS %d\n",nmachregs); + fprintf(hfile,"#define REGSETSIZE %d\n",(nmachregs+15)>>4); + fprintf(hfile,"#define TOKENSIZE %d\n",maxtokensize); + fprintf(hfile,"#define MAXMEMBERS %d\n",maxmembers); + fprintf(hfile,"#define LONGESTPATTERN %d\n",maxempatlen); + fprintf(hfile,"#define MAXRULE %d\n",maxrule); + fprintf(hfile,"#define NMOVES %d\n",nmoves); + fprintf(hfile,"#define NC1 %d\n",nc1); + if (nc2) { + assert(maxsplit!=0); + fprintf(hfile,"#define NC2 %d\n",nc2); + fprintf(hfile,"#define MAXSPLIT %d\n",maxsplit); + } + fprintf(hfile,"#define NC3 %d\n",nc3); + outregs(); + fprintf(cfile,"tkdef_t tokens[] = {\n"); + for(i=0;iex_operator,np->ex_lnode, + np->ex_rnode); + fprintf(cfile,"};\n\nstring codestrings[] = {\n"); + for(i=0;im_set1, mp->m_expr1, + mp->m_set2, mp->m_expr2, + mp->m_cindex, + mp->m_cost.c_size,mp->m_cost.c_time); + } + fprintf(cfile,"};\n\nbyte pattern[] = {\n"); + for (i=0;irregvar<0 && + (machprops[i].propset.set_val[j>>4]&(1<<(j&017)))) + fprintf(cfile,"\t&machregs[%d],\n",j-1); + } + fprintf(cfile,"\t0\n};\n"); + } + fprintf(cfile,"struct reginfo **reglist[] = {\n"); + for (i=0;i0) + fprintf(cfile,"struct regassigned ratar%d[%d];\n", + i,nregvar[i]); + for (i=0;i<4;i++) if (nregvar[i]>0) { + fprintf(cfile,"int rvtar%d[] = {",i); + for (j=0;j0) + fprintf(cfile,"\trvtar%d,\n",i); + else + fprintf(cfile,"\t0,\n"); + fprintf(cfile,"};\n\nstruct regassigned *regassigned[] = {\n"); + for (i=0;i<4;i++) + if (nregvar[i]>0) + fprintf(cfile,"\tratar%d,\n",i); + else + fprintf(cfile,"\t0,\n"); + fprintf(cfile,"};\n"); +} + +verbose() { + + fprintf(stderr,"Codebytes %d\n",codebytes); + fprintf(stderr,"Registers %d(%d)\n",nmachregs,MAXREGS); + fprintf(stderr,"Properties %d(%d)\n",nprops,MAXPROPS); + fprintf(stderr,"Tokens %d(%d)\n",nmachtokens,MAXTOKENS); + fprintf(stderr,"Sets %d(%d)\n",nmachsets,MAXSETS); + fprintf(stderr,"Tokeninstances %d(%d)\n",narinstance,MAXINSTANCE); + fprintf(stderr,"Strings %d(%d)\n",ncodestrings,MAXSTRINGS); + fprintf(stderr,"Enodes %d(%d)\n",lastnode-nodes,MAXNODES); + fprintf(stderr,"Patbytes %d(%d)\n",npatbytes,MAXPATTERN); +} + +inbetween() { + register ident_p ip; + register i,j; + register move_p mp; + + lookident=1; /* for lexical analysis */ + + chktabsiz(nmachsets+1,MAXSETS,"Expressiontable"); + for (i=0;ii_type=IEXP; + ip->i_i.i_expno = nmachsets++; + + for (i=0;ii_type=IEXP; + allexpno = ip->i_i.i_expno = nmachsets++; + mp = &machmoves[nmoves++]; + mp->m_set1 = cocosetno; + mp->m_expr1 = 0; + mp->m_set2 = nmachsets-1; + mp->m_expr2 = 0; + mp->m_cindex = 0; + mp->m_cost.c_size = 0; + mp->m_cost.c_time = 0; + + /* + * Create sets of registers per property + */ + + for (i=0;irprop[i>>4]&(1<<(i&017))) + sp[j>>4] |= (1<<(j&017)); + } +} + +formconversion(p,tp) register char *p; register token_p tp; { + char buf[256]; + register char *q=buf; + char field[256]; + register char *f; + int i; + + if (p==0) + return(0); + while (*p) switch(*p) { + default: *q++ = *p++; continue; + case '%': + p++; + if(*p == '%') { + *q++ = *p++; + continue; + } + if (*p == '[') + p++; + else + yyerror("Bad character after % in format"); + f=field; + while (*p != 0 && *p != ']') + *f++ = *p++; + *f++ = 0; + if (*p == ']') + p++; + else + yyerror("Unterminated %[] construct in format"); + for (i=0;it_fields[i].t_sname)==0) + break; + if (i==TOKENSIZE-1) + yyerror("Unknown field in %[] construct in format"); + *q++ = i+1; + } + *q++ = 0; + return(strlookup(buf)); +} + +setfields(tp,format) register token_p tp; string format; { + register i; + list2 ll; + register list1 l; + int type; + + for(i=0;it_fields[i].t_type = 0; + i=0; + for(ll=tp->t_struct;ll!=0;ll=ll->l2next) { + l=ll->l2list; + if(strcmp(l->l1name,"REGISTER")==0) + type = TYPREG; + else if (strcmp(l->l1name,"INT")==0) + type = TYPINT; + else type = TYPSTR; + for(l=l->l1next;l!=0;l=l->l1next) { + tp->t_fields[i].t_type = type; + tp->t_fields[i].t_sname = l->l1name; + i++; + } + } + if (format != 0) + tp->t_format = formconversion(format,tp); + else + tp->t_format = -1; +} + +chkregexp(number) { + register i; + + for(i=nmachregs+1;i>4]&(01<<(i&017))) + yyerror("No tokens allowed in this set"); +} + +findstructel(number,name,t) string name; int *t; { + register i; + register token_p tp; + register list2 structdecl; + int offset; + + for(i=1;i<=nmachregs;i++) + if (machsets[number].set_val[i>>4]&(01<<(i&017))) + yyerror("No registers allowed in this set"); + structdecl = 0; + for (i=nmachregs+1;i>4]&(01<<(i&017))) { + if (structdecl == 0) { + structdecl = machtokens[i-(nmachregs+1)].t_struct; + tp = &machtokens[i-(nmachregs+1)]; + } else if(structdecl != machtokens[i-(nmachregs+1)].t_struct) + yyerror("Multiple structs in this set"); + } + } + if (structdecl == 0) { + yyerror("No structs in this set"); + return(0); + } + for(offset=0;offsett_fields[offset].t_type != 0 && + strcmp(tp->t_fields[offset].t_sname,name)==0) { + *t = tp->t_fields[offset].t_type; + return(offset+1); + } + yyerror("No such field in this struct"); + return(0); +} + +extern char em_flag[]; + +argtyp(mn) { + + switch(em_flag[mn-sp_fmnem]&EM_PAR) { + case PAR_W: + case PAR_S: + case PAR_Z: + case PAR_O: + case PAR_N: + case PAR_L: + case PAR_F: + case PAR_R: + case PAR_C: + return(TYPINT); + default: + return(TYPSTR); + } +} + +commontype(e1,e2) expr_t e1,e2; { + + if(e1.expr_typ != e2.expr_typ) + yyerror("Type incompatibility"); + return(e1.expr_typ); +} + +extern char em_mnem[][4]; + +#define HASHSIZE (2*(sp_lmnem-sp_fmnem)) + +struct hashmnem { + char h_name[3]; + byte h_value; +} hashmnem[HASHSIZE]; + +inithash() { + register i; + + for(i=0;i<=sp_lmnem-sp_fmnem;i++) + enter(em_mnem[i],i+sp_fmnem); +} + +enter(name,value) char *name; { + register unsigned h; + + h=hash(name)%HASHSIZE; + while (hashmnem[h].h_name[0] != 0) + h = (h+1)%HASHSIZE; + strncpy(hashmnem[h].h_name,name,3); + hashmnem[h].h_value = value; +} + +int mlookup(name) char *name; { + register unsigned h; + + h = hash(name)%HASHSIZE; + while (strncmp(hashmnem[h].h_name,name,3) != 0 && + hashmnem[h].h_name[0] != 0) + h = (h+1)%HASHSIZE; + return(hashmnem[h].h_value&BMASK); /* 0 if not found */ +} + +hashpatterns() { + short index; + register byte *bp,*tp; + register short i; + unsigned short hashvalue; + int patlen; + + index = prevind; + while (index != 0) { + bp = &pattern[index]; + tp = &bp[PO_MATCH]; + i = *tp++&BMASK; + if (i==BMASK) { + i = *tp++&BMASK; + i |= (*tp++&BMASK)<>BSHIFT; + hashvalue &= BMASK; + bp[PO_NEXT] = pathash[hashvalue]&BMASK; + bp[PO_NEXT+1] = pathash[hashvalue]>>BSHIFT; + pathash[hashvalue] = i; + } +} + +debug() { + register i,j; + + for(i=0;ii_next) + printf("%-14s %1d %3d\n",ip->i_name, + ip->i_type,ip->i_i.i_regno); + } + + for(i=2;irname,rp->rrepr,rp->rsize); + for(j=0;jrmembers[j] != 0) + printf(", %s",machregs[rp->rmembers[j]]->rname); + printf(")"); + for(j=0;jrprop[j>>4]&(1<<(j&017))) + printf(", %s",machprops[j].propname->i_name); + printf(".\n"); + } +} + +out(n) { + + assert(n>=0); + if (n<128) + outbyte(n); + else { + outbyte(n/256+128); + outbyte(n%256); + } +} + +outbyte(n) { + + fprintf(cfile,"%d, ",n&BMASK); + codebytes++; +} + +pat(n) { + + assert(n>=0); + if (n<128) + patbyte(n); + else { + patbyte(n/256+128); + patbyte(n%256); + } +} + +patshort(n) { + + patbyte(n&BMASK); + patbyte(n>>BSHIFT); +} + +patbyte(n) { + + chktabsiz(npatbytes,MAXPATTERN,"Pattern table"); + pattern[npatbytes++] = n; +} + +max(a,b) { + + if (a>b) + return(a); + return(b); +} + +#include "bootlex.c" diff --git a/util/cgg/bootlex.l b/util/cgg/bootlex.l new file mode 100644 index 000000000..b5d5b4c2f --- /dev/null +++ b/util/cgg/bootlex.l @@ -0,0 +1,185 @@ +%{ +/* + * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. + * + * This product is part of the Amsterdam Compiler Kit. + * + * Permission to use, sell, duplicate or disclose this software must be + * obtained in writing. Requests for such permissions may be sent to + * + * Dr. Andrew S. Tanenbaum + * Wiskundig Seminarium + * Vrije Universiteit + * Postbox 7161 + * 1007 MC Amsterdam + * The Netherlands + * + * Author: Hans van Staveren + */ + +#undef input +#undef output +#undef unput + +#define MAXBACKUP 50 +%} +%% +"/*" { char c; + c = input(); + do { + while (c!='*') + c = input(); + c = input(); + } while (c!='/'); + } +"REGISTERS:" return(REGISTERHEAD); +"TOKENS:" return(TOKENHEAD); +"TOKENEXPRESSIONS:" return(EXPRESSIONHEAD); +"CODE:" return(CODEHEAD); +"MOVES:" return(MOVEHEAD); +"TESTS:" return(TESTHEAD); +"STACKS:" return(STACKHEAD); +"SIZEFACTOR" return(SIZEFAC); +"TIMEFACTOR" return(TIMEFAC); +"FORMAT" return(FORMAT); + +"cost" return(COST); +"remove" return(REMOVE); +"|" return(SEP); +"samesign" return(SAMESIGN); +"inreg" return(INREG); +"sfit" return(SFIT); +"ufit" return(UFIT); +"defined" return(DEFINED); +"rom" return(ROM); +"loww" return(LOWW); +"highw" return(HIGHW); +"move" return(MOVE); +"erase" return(ERASE); +"allocate" return(ALLOCATE); +"tostring" return(TOSTRING); +"nocc" return(NOCC); +"setcc" return(SETCC); +"samecc" return(SAMECC); +"test" return(TEST); +"STACK" return(STACK); +"nocoercions" return(NOCOERC); + +"&&" return(AND2); +"||" return(OR2); +"==" return(CMPEQ); +"!=" return(CMPNE); +"<=" return(CMPLE); +"<" return(CMPLT); +">" return(CMPGT); +">=" return(CMPGE); +">>" return(RSHIFT); +"<<" return(LSHIFT); +"!" return(NOT); +"~" return(COMP); +"..." return(ELLIPS); + +EM_WSIZE { yylval.yy_intp = &wsize; return(CIDENT); } +EM_PSIZE { yylval.yy_intp = &psize; return(CIDENT); } +EM_BSIZE { yylval.yy_intp = &bsize; return(CIDENT); } +REGISTER { yylval.yy_string = "REGISTER"; return(TYPENAME); } +INT { yylval.yy_string = "INT"; return(TYPENAME); } +STRING { yylval.yy_string = "STRING"; return(TYPENAME); } + +regvar return(REGVAR); +loop return(LOOP); +pointer return(POINTER); +float return(FLOAT); +return return(RETURN); + +[_A-Za-z][_A-Za-z0-9]+ {register ident_p ip; + if(!lookident || (ip=ilookup(yytext,JUSTLOOKING))==0) { + yylval.yy_string = scopy(yytext);return(IDENT); + } else { + yylval.yy_ident = ip; + switch(ip->i_type) { + default:assert(0); + case IREG:return(RIDENT); + case IPRP:return(PIDENT); + case ITOK:return(TIDENT); + case IEXP:return(EIDENT); + } + } + } +[a-z] {yylval.yy_char = yytext[0]; return(LCASELETTER);} +[0-9]* {yylval.yy_int = atoi(yytext);return(NUMBER);} +(\"|"%)") { char *p; int c,tipe; + p=yytext; + for (;;) { + c = input(); + switch(c) { + default: *p++=c;break; + case '\\': + *p++=c; *p++=input(); break; + case '\n': + yyerror("Unterminated string"); + break; + case '"': + tipe=STRING; goto endstr; + case '%': + c=input(); + if (c == '(') { + tipe=LSTRING;goto endstr; + } else { + *p++ = '%'; unput(c); break; + } + } + } + endstr: + *p++ = 0; + yylval.yy_string = scopy(yytext); + return(tipe); + } +[ \t]* | +\n ; +. return(yytext[0]); +%% + +char linebuf[256]; +char prevbuf[256]; +int linep; +int linepos; /* corrected for tabs */ +char charstack[MAXBACKUP]; +int nbackup=0; + +output(c) { + + assert(0); +} + +input() { + + if(nbackup) + return(charstack[--nbackup]); + if(linebuf[linep]==0) { + strcpy(prevbuf,linebuf); + if(fgets(linebuf,256,stdin)==NULL) + return(0); + lino++; + linepos=linep=0; + } + if (linebuf[linep] == '\t') + linepos = (linepos+8) & ~07; + else linepos++; + return(linebuf[linep++]); +} + +unput(c) { + + chktabsiz(nbackup,MAXBACKUP,"Lexical backup table"); + charstack[nbackup++] = c; +} + +yyerror(s,a1,a2,a3,a4) string s; { + + fprintf(stderr,"%d\t%s%d\t%s\t%*c ",lino-1,prevbuf,lino,linebuf, + linepos-1,'^'); + fprintf(stderr,s,a1,a2,a3,a4); + fprintf(stderr,"\n"); + nerrors++; +}