diff --git a/util/ncgg/Makefile b/util/ncgg/Makefile new file mode 100644 index 000000000..293394670 --- /dev/null +++ b/util/ncgg/Makefile @@ -0,0 +1,171 @@ +# $Header$ + +CFILES=cgg.c subr.c main.c coerc.c enterkeyw.c error.c emlookup.c expr.c instruct.c iocc.c lookup.c output.c set.c strlookup.c var.c hall.c +OFILES=cgg.o subr.o main.o coerc.o enterkeyw.o error.o emlookup.o expr.o instruct.o iocc.o lookup.o set.o strlookup.o var.o hall.o +SOURCES=*.h cgg.y scan.l cvtkeywords keywords coerc.c emlookup.c error.c expr.c hall.c instruct.c iocc.c lookup.c main.c output.c set.c strlookup.c subr.c var.c +EMH=../../h +CFLAGS=-I$(EMH) +YFLAGS=-v -d + + +cgg: cgg.o $(OFILES) output.o + cc $(LDFLAGS) $(OFILES) output.o ../../lib/em_data.a -ll -o cgg + +install: cgg + cp cgg ../../lib/ncgg + +cmp: cgg + cmp cgg ../../lib/ncgg + +debugcgg: cgg.o $(OFILES) debugoutput.o + cc $(LDFLAGS) $(OFILES) debugoutput.o ../../lib/em_data.a -ll -o cgg + +cgg.o: scan.c + +enterkeyw.c: cvtkeywords keywords y.tab.h + cvtkeywords + +debugoutput.o: debugoutput.c + $(CC) $(CFLAGS) -DCODEDEBUG -c debugoutput.c + +debugoutput.c: output.c + cp output.c debugoutput.c + +lint: $(CFILES) + lint $(CFLAGS) $(CFILES) + touch lint + +clean: + rm -f cgg.c scan.c y.output y.tab.h enterkeyw.c + rm -f $(OFILES) output.o debugoutput.o cgg lint + +pr: + pr $(SOURCES) + +lpr: + make pr|lpr + +depend: + makedepend + +cgg.o: $(EMH)/cgg_cg.h +coerc.o: $(EMH)/cgg_cg.h +debugoutput.o: $(EMH)/cgg_cg.h +expr.o: $(EMH)/cgg_cg.h +instruct.o: $(EMH)/cgg_cg.h +iocc.o: $(EMH)/cgg_cg.h +output.o: $(EMH)/cgg_cg.h +set.o: $(EMH)/cgg_cg.h +subr.o: $(EMH)/cgg_cg.h +var.o: $(EMH)/cgg_cg.h +# AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO +cgg.o: expr.h +cgg.o: extern.h +cgg.o: instruct.h +cgg.o: iocc.h +cgg.o: lookup.h +cgg.o: param.h +cgg.o: scan.c +cgg.o: set.h +cgg.o: varinfo.h +coerc.o: assert.h +coerc.o: extern.h +coerc.o: iocc.h +coerc.o: param.h +coerc.o: property.h +coerc.o: pseudo.h +coerc.o: reg.h +coerc.o: set.h +coerc.o: token.h +coerc.o: varinfo.h +debugoutput.o: assert.h +debugoutput.o: extern.h +debugoutput.o: instruct.h +debugoutput.o: lookup.h +debugoutput.o: param.h +debugoutput.o: property.h +debugoutput.o: pseudo.h +debugoutput.o: reg.h +debugoutput.o: regvar.h +debugoutput.o: set.h +debugoutput.o: token.h +debugoutput.o: varinfo.h +emlookup.o: expr.h +emlookup.o: param.h +enterkeyw.o: lookup.h +expr.o: assert.h +expr.o: expr.h +expr.o: extern.h +expr.o: lookup.h +expr.o: param.h +expr.o: property.h +expr.o: reg.h +expr.o: regvar.h +expr.o: set.h +expr.o: token.h +hall.o: assert.h +hall.o: param.h +hall.o: set.h +instruct.o: expr.h +instruct.o: extern.h +instruct.o: instruct.h +instruct.o: iocc.h +instruct.o: param.h +instruct.o: pseudo.h +instruct.o: set.h +instruct.o: varinfo.h +iocc.o: assert.h +iocc.o: expr.h +iocc.o: extern.h +iocc.o: iocc.h +iocc.o: lookup.h +iocc.o: param.h +iocc.o: property.h +iocc.o: regvar.h +iocc.o: set.h +iocc.o: token.h +lookup.o: assert.h +lookup.o: lookup.h +lookup.o: param.h +output.o: assert.h +output.o: extern.h +output.o: instruct.h +output.o: lookup.h +output.o: param.h +output.o: property.h +output.o: pseudo.h +output.o: reg.h +output.o: regvar.h +output.o: set.h +output.o: token.h +output.o: varinfo.h +scan.o: stdio.h +set.o: extern.h +set.o: lookup.h +set.o: param.h +set.o: property.h +set.o: set.h +set.o: token.h +strlookup.o: param.h +subr.o: expr.h +subr.o: extern.h +subr.o: instruct.h +subr.o: lookup.h +subr.o: param.h +subr.o: property.h +subr.o: reg.h +subr.o: regvar.h +subr.o: set.h +subr.o: token.h +subr.o: varinfo.h +tables.o: data.h +tables.o: param.h +tables.o: tables.h +tables.o: types.h +var.o: instruct.h +var.o: lookup.h +var.o: param.h +var.o: property.h +var.o: reg.h +var.o: set.h +var.o: token.h diff --git a/util/ncgg/cgg.y b/util/ncgg/cgg.y new file mode 100644 index 000000000..37ece481c --- /dev/null +++ b/util/ncgg/cgg.y @@ -0,0 +1,992 @@ +%{ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "param.h" +#include "varinfo.h" +#include "lookup.h" +#include "set.h" +#include "iocc.h" +#include "instruct.h" +#include "expr.h" +#include "extern.h" +#include +#include + +extern int lineno; +int instline,saveline; +int startline; +int npatterns; +int patindex[MAXPATTERNS]; + +int emhere=0; /* lexical analyzer flag */ +int optexact=0; /* Inside "with exact" rule */ +int optstack=0; /* Inside with STACK rule */ +int saferulefound=0; +int maxempatlen=0; +int maxrule=0; +struct varinfo *defcost; + +struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab(); +struct varinfo *make_erase(); +expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr(); +expr_t perc_ident_expr(),sum_expr(),regvar_expr(); + +set_t ident_to_set(),setproduct(),setsum(),setdiff(); + +iocc_t subr_iocc(),tokm_iocc(),ident_iocc(),all_iocc(),descr_iocc(); + +extern int narexpr; +extern expr_t arexp[]; + +int niops; +iocc_t iops[20]; +%} + +%union { + int yy_int; + char * yy_str; + varinfo * yy_varinfo; + set_t yy_set; + operand *yy_oplist; + expr_t yy_expr; + iocc_t yy_iocc; +} + +%token PROPERTIES +%token REGISTERS +%token TOKENS +%token SETS +%token MOVES +%token TESTS +%token STACKINGRULES COERCIONS +%token INSTRUCTIONS +%token PROC CALL EXAMPLE +%token FROM TO +%token TEST MOVE STACK RETURN +%token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING +%token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW +%token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP +%token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER +%token ADORNACCESS +%token ADORNCC +%token INT +%token ADDR +%token EMMNEM +%token NUMBER +%token DOLLAR PERCENT ALLREG +%token IDENT PERC_IDENT +%token STRING +%token TIMEFACTOR SIZEFACTOR +%token COST +%type prop_list property ident_list ident_list_el +%type att_list att_list_el structdecl optcost optformat +%type kills allocates yields leaving +%type generates kill_list kill_list_el uselist uselist_el genlist yieldlist +%type leavelist leavelist_el gen_instruction +%type opt_erase_list erase_list erase_list_el +%type opt_par_string optstring +%type register propno att_list_el_type tokenset_no +%type adornlist optstar optuses optregvar regvartype optregvartype +%type emarg tokarg subreg allreg optsecondstring +%type expr +%type tokeninstance +%type optexpr optexact optstack +%type tokenset +%type oplist oplist_el + +%left OR2 +%left AND2 +%left CMPEQ,CMPNE +%left CMPLT,CMPLE,CMPGT,CMPGE +%left RSHIFT,LSHIFT +%left '+','-' +%left '*','/','%' +%nonassoc NOT,COMP,UMINUS + +%start machtable + +%% +/* + * The machine table consists of a number of sections, with their + * own associated parsers. + */ +machtable + : constants + properties + registers + tokens + { make_std_sets(); } + sets + instructions + moves + tests + stacks + coercs + code + ; + +/* + * Constants are parsed as name=value pairs + */ +constants + : constdeflist + ; +constdeflist + : /* empty */ + | constdeflist constdef + ; +constdef + : IDENT'=' NUMBER + { n_const($1,$3); free($1); } + | IDENT '=' STRING + { n_sconst($1,$3); free($1); free($3); } + | TIMEFACTOR '=' NUMBER '/' NUMBER + { fc1 = $3; fc2 = $5; } + | SIZEFACTOR '=' NUMBER '/' NUMBER + { fc3 = $3; fc4 = $5; } + | error + ; + +/* + * Properties are parsed as a list of names optionally followed by their size + */ +properties + : PROPERTIES { make_const(); } prdef_list + ; +prdef_list + : prdef_list_el + | prdef_list optcomma prdef_list_el + ; +prdef_list_el + : IDENT + { n_prop($1,wordsize); free($1); } + | IDENT '(' NUMBER ')' + { n_prop($1,$3); free($1); } + ; + +/* + * Registers are rows of reglist:proplist pairs + */ +registers + : REGISTERS regdef_list + ; +regdef_list + : regdef_list_el + | regdef_list regdef_list_el + ; +regdef_list_el + : ident_list ':' prop_list optregvar '.' + { regline($1,$3,$4); free((char *) $1); free((char *) $3); } + | error '.' + ; +optregvar + : /* empty */ + { $$ = -1; } + | REGVAR + { $$ = reg_any; } + | REGVAR '(' regvartype ')' + { $$ = $3; } + ; + +regvartype + : REG_ANY + { $$ = reg_any;} + | REG_FLOAT + { $$ = reg_float;} + | REG_LOOP + { $$ = reg_loop;} + | REG_POINTER + { $$ = reg_pointer;} + ; + +ident_list + : ident_list_el + | ident_list optcomma ident_list_el + { $3->vi_next = $1; $$ = $3; } + ; +ident_list_el + : IDENT opt_par_string + { NEW($$,struct varinfo); + $$->vi_next = 0; + $$->vi_int[0] = n_reg($1,$2,0,0,0); + free($1); if($2!=0) free($2); + } + | IDENT opt_par_string '=' register + { NEW($$,struct varinfo); + $$->vi_next = 0; + $$->vi_int[0] = n_reg($1,$2,1,$4,0); + free($1); if($2!=0) free($2); + } + | IDENT opt_par_string '=' register '+' register + { NEW($$,struct varinfo); + $$->vi_next = 0; + $$->vi_int[0] = n_reg($1,$2,2,$4,$6); + free($1); if($2!=0) free($2); + } + ; +opt_par_string + : /* empty */ + { $$ = 0; } + | '(' STRING ')' + { $$ = $2; } + ; +register + : IDENT + { register symbol *sy_p; + + sy_p = lookup($1,symreg,mustexist); + $$ = sy_p->sy_value.syv_regno; + free($1); + } + ; +prop_list + : property + | prop_list optcomma property + { $3->vi_next = $1; $$ = $3; } + ; +property + : IDENT + { register symbol *sy_p; + sy_p = lookup($1,symprop,mustexist); + NEW($$,struct varinfo); + $$->vi_next=0; + $$->vi_int[0]=sy_p->sy_value.syv_propno; + free($1); + } + ; +propno + : IDENT + { register symbol *sy_p; + sy_p = lookup($1,symprop,mustexist); + $$ = sy_p->sy_value.syv_propno; + free($1); + } + ; + +/* tokens are parsed as struct definitions + * types in the struct can be register properties, ADDR or INT + */ + +tokens + : TOKENS tokdeflist + ; +tokdeflist + : tokdeflist_el + | tokdeflist tokdeflist_el + ; +tokdeflist_el + : IDENT '=' structdecl NUMBER optcost optformat '.' + { n_tok($1,$3,$4,$5,$6); + free($1); + freevi($3); + freevi($5); + freevi($6); + } + | error '.' + ; +structdecl + : '{' att_list '}' + { $$ = $2; } + ; +att_list + : /* empty */ + { $$ = 0; } + | att_list_el att_list + { $1->vi_next = $2; $$ = $1; } + ; +att_list_el + : att_list_el_type IDENT ';' + { NEW ($$,struct varinfo); + $$->vi_next = 0; + $$->vi_int[0] = $1; + $$->vi_str[0] = $2; + } + ; +att_list_el_type + : INT + { $$ = -1; } + | ADDR + { $$ = -2; } + | propno + ; +optcost + : + { if (defcost==VI_NULL) + $$=VI_NULL; + else { + NEW($$,struct varinfo); + *$$ = *defcost; + } + } + | COST '(' NUMBER ',' NUMBER ')' + { NEW ($$,struct varinfo); + $$->vi_int[0] = $3; + $$->vi_int[1] = $5; + } + ; +optformat + : + { $$ = 0; } + | STRING optformat + { NEW($$,struct varinfo); + $$->vi_next = $2; + $$->vi_int[0] = 0; + $$->vi_str[0] = $1; + } + | IDENT optformat + { NEW($$,struct varinfo); + $$->vi_next = $2; + $$->vi_int[0] = 1; + $$->vi_str[0] = $1; + } + ; +optcomma + : ',' + | /* empty */ + ; + +/* sets are parsed as ident = expression */ + +sets + : SETS setdeflist + ; +setdeflist + : setdeflist_el + | setdeflist setdeflist_el + ; +setdeflist_el + : IDENT '=' tokenset_no '.' + { n_set($1,$3); free($1); } + | error '.' + ; +tokenset_no + : tokenset + { $$ = setlookup($1); } + ; +tokenset + : IDENT + { $$ = ident_to_set($1); free($1); } + | tokenset '*' tokenset + { $$ = setproduct($1,$3); } + | tokenset '+' tokenset + { $$ = setsum($1,$3); } + | tokenset '-' tokenset + { $$ = setdiff($1,$3); } + | '(' tokenset ')' + { $$ = $2; } + ; + +instructions + : INSTRUCTIONS optcost instdef_list + { defcost = $2; } + ; +instdef_list + : instdef_list_el + | instdef_list instdef_list_el + ; +instdef_list_el + : IDENT optstring oplist opt_erase_list optcost '.' + { n_instr($1,$2,$3,$4,$5); freevi($5); } + | error '.' + ; +oplist + : /* empty */ + { $$ = 0; } + | oplist_el + | oplist_el ',' oplist + { $$ = $1; $$->o_next = $3; } + ; +oplist_el + : tokenset_no adornlist + { NEW($$,struct operand); + $$->o_next = 0 ; + $$->o_setno = $1; + $$->o_adorn = $2; + checkprintformat($1); + } + ; +adornlist + : /* empty */ + { $$ = 0; } + | ADORNACCESS adornlist + { if ($2&AD_RWMASK) + error("Only one of :ro,:wo,:rw allowed"); + $$ = $1 | $2; + } + | ADORNCC adornlist + { $$ = $1|$2; } + ; +opt_erase_list + : /* empty */ + { $$ = VI_NULL;} + | KILLS erase_list + { $$ = $2; } + ; +erase_list + : erase_list_el + { $$ = $1; } + | erase_list_el erase_list + { $1->vi_next = $2; $$ = $1; } + ; +erase_list_el + : IDENT + { $$ = make_erase($1); } + | ADORNCC + { NEW($$, struct varinfo); + $$->vi_int[0] = -1; + $$->vi_next = VI_NULL; + } + ; + +/* Now the moves */ + +moves + : MOVES movedeflist + | /* empty */ + ; +movedeflist + : movedeflist_el + | movedeflist movedeflist_el + ; +movedeflist_el + : FROM + {startline = lineno; } + tokenset_no + { cursetno = $3; } + optexpr TO tokenset_no + { cursetno = $7; + tokpatlen=2; + tokpatset[0] = $3; + tokpatset[1] = $7; + tokpatro[0] = 1; + } + optexpr GEN genlist + { tokpatlen=0; + tokpatro[0]=0; + n_move($3,$5,$7,$9,$11); + freevi($11); + } + | error + ; + +/* Now the test part */ + +tests + : TESTS testdeflist + | /* empty */ + ; +testdeflist + : testdeflist_el + | testdeflist testdeflist_el + ; +testdeflist_el + : TO + { startline = lineno;} + TEST tokenset_no + { cursetno = $4; + tokpatlen=1; + tokpatset[0]=$4; + tokpatro[0] = 1; + } + optexpr GEN genlist + { tokpatlen=0; + tokpatro[0] = 0; + n_test($4,$6,$8); + freevi($8); + } + | error + ; + +/* Now the stacks */ + +stacks + : STACKINGRULES stackdeflist + ; +stackdeflist + : stackdeflist_el + | stackdeflist stackdeflist_el + ; +stackdeflist_el + : FROM + {startline = lineno;} + tokenset_no + { cursetno = $3; + tokpatlen=1; + tokpatset[0] = $3; + tokpatro[0] = 1; + } + optexpr TO STACK optuses GEN genlist + { tokpatro[0] = 0; + n_stack($3,$5,$8,$10); + freevi($10); + } + ; +optuses + : /* empty */ + { $$ = 0; nallreg=0;} + | USES propno + { $$ = $2; nallreg = 1; allreg[0] = $2; } + ; + +/* Now the one-to-one coercion rules */ + +coercs + : COERCIONS coercdeflist + ; +coercdeflist + : coercdeflist_el + | coercdeflist coercdeflist_el + ; +coercdeflist_el + : FROM + {startline = lineno; tokpatlen=0; inithall();} + STACK allocates GEN genlist YIELDS tokeninstance + { checkhall(); + n_coerc(0,0,$4,$6,(struct varinfo *) 0,$8); + freevi($4); + freevi($6); + } + | FROM + {startline = lineno;} + tokenset_no + { cursetno = $3; + tokpatlen=1; + tokpatset[0]=$3; + tokpatro[0] = 1; + inithall(); + } + optexpr allocates generates yields + { tokpatro[0] = 0; + checkhall(); + n_coerc($3,$5,$6,$7,$8); + freevi($6); + freevi($7); + } + ; + +/* Now the code part */ + +code + : PATTERNS coderules + ; +coderules + : coderule + | coderules coderule + ; +coderule + : PAT {emhere=1;} empattern {emhere=0;} optexpr + { empatexpr = $5; + npatterns = 0; + saferulefound=0; + if (empatlen>maxempatlen) + maxempatlen=empatlen; + } + patterns + { if (!saferulefound) + error("Previous rule impossible on empty stack"); + outpatterns(); + } + | PROC IDENT example + { npatterns = 0; saferulefound=0; inproc=1; n_proc($2); } + patterns + { if (!saferulefound) + error("Previous rule impossible on empty stack"); + outpatterns(); inproc=0; + } + | error + { skipupto(PAT,"pat"); yyerrok; yyclearin; } + ; +example + : /* empty */ + { empatlen = 0; } + | EXAMPLE {emhere=1;} empattern {emhere=0;} + ; +empattern + : EMMNEM + { empatlen = 1; emmnem[0] = $1; } + | empattern EMMNEM + { NEXT(empatlen,EMPATMAX,"Em pattern"); + emmnem[empatlen-1] = $2; + } + ; +patterns + : onepattern + { saferulefound=1; + callproc=0; + } + | morepatterns + { callproc=0; + if (npatterns>maxrule) + maxrule=npatterns; + } + | CALL IDENT '(' STRING optsecondstring ')' + { register symbol *sy_p; + saferulefound=1; + sy_p=lookup($2,symproc,mustexist); + callproc=sy_p->sy_value.syv_procoff; + procarg[0] = strlookup($4); + procarg[1] = $5; + free($2); + free($4); + } + ; +optsecondstring + : /* empty */ + { $$ = 0; } + | ',' STRING + { $$ = strlookup($2); free($2); } + ; + +onepattern + : { inithall(); startline=lineno; tokpatlen=0; } + kills allocates generates yields leaving + { optexact=0; optstack=0; + patindex[npatterns++]=codeindex; + checkhall(); + dopattern(0,$2,$3,$4,$5,$6); + freevi($2); + freevi($3); + freevi($4); + freevi($5); + freevi($6); + } + ; +morepatterns + : { inithall(); } pattern + | morepatterns { inithall(); } pattern + ; + +pattern + : stackpattern kills allocates generates yields leaving + { patindex[NEXT(npatterns,MAXPATTERNS,"Patterns")]=codeindex; + if (hall() && !optexact) saferulefound=1; + dopattern(0,$2,$3,$4,$5,$6); + freevi($2); + freevi($3); + freevi($4); + freevi($5); + freevi($6); + } + ; +stackpattern + : WITH optexact + { startline = lineno; } + setlist optstack + ; +optexact + : /* empty */ + { $$ = optexact = 0; } + | EXACT + { $$ = optexact = 1; } + ; +optstack + : /* empty */ + { $$ = optstack = 0; } + | STACK + { $$ = optstack = 1; } + ; + +setlist + : /* empty */ + { tokpatlen = 0; } + | setlist tokenset_no + { NEXT(tokpatlen,TOKPATMAX,"Stack pattern"); + tokpatset[tokpatlen-1] = $2; + checkunstacking($2); + } + ; +kills + : /* empty */ + { $$ = 0; } + | KILLS kill_list + { $$ = $2; + if (optstack) + error("No sense in giving kills in this pattern"); + } + ; +kill_list + : kill_list_el + | kill_list_el ',' kill_list + { $$=$1; $$->vi_next = $3; } + ; +kill_list_el + : tokenset_no { cursetno=$1; } optexpr + { NEW($$,struct varinfo); + $$->vi_next = 0; + $$->vi_int[0]=$1; + $$->vi_int[1]=$3; + } + ; +allocates + : /* empty */ + { $$ = 0; nallreg=0;} + | USES uselist + { $$ = $2; setallreg($2); } + ; +uselist + : uselist_el + { prophall($1->vi_int[0]); } + | uselist_el ',' uselist + { prophall($1->vi_int[0]); $$=$1; $$->vi_next=$3; } + ; +uselist_el + : property + { $$=$1; $$->vi_int[1] = 0; } + | property '=' tokeninstance + { if (!existalmove($3,$$->vi_int[0])) + error("No such move defined"); + $$=$1; $$->vi_int[1] = $3.in_index; + } + | REUSING tokeninstance + { NEW($$,struct varinfo); + $$->vi_next = 0; + $$->vi_int[0] = -1; + $$->vi_int[1] = $2.in_index; + } + ; + + +generates + : /* empty */ + { $$ = 0; } + | GEN genlist + { $$ = $2; } + ; +genlist + : /* empty */ + { $$ = 0; } + | gen_instruction genlist + { if ($1!=0) { + register struct varinfo *tvip; + $$=tvip=$1; + while (tvip->vi_next!=VI_NULL) + tvip=tvip->vi_next; + tvip->vi_next = $2; + } else { + $$ = $2; + } + } + ; +gen_instruction + : {instline = lineno; } IDENT optstar gen_oplist + { saveline =lineno; lineno=instline; + $$ = gen_inst($2,$3); free($2); + lineno = saveline; + } + | NUMBER ':' + { $$ = gen_tlab($1); } + | MOVE tokeninstance ',' tokeninstance + { $$ = gen_move($2,$4); } + | TEST tokeninstance + { $$ = gen_test($2);} + | RETURN + { $$ = gen_preturn(); } + ; +optstar + : /* empty */ + { $$=0; } + | '*' + { $$=1; } + | '[' NUMBER ']' + { $$=$2; } + ; +gen_oplist + : '.' /* empty gives conflicts */ + { niops=0; } + | tokeninstance + { niops=1;iops[0]=$1; } + | gen_oplist ',' tokeninstance + { iops[niops++] = $3; } + ; + +yields + : /* empty */ + { $$ = 0; } + | YIELDS yieldlist + { $$ = $2; } + ; +yieldlist + : /* empty */ + { $$ = 0; } + | tokeninstance yieldlist + { checkstacking($1.in_set); + NEW($$,struct varinfo); + $$->vi_next = $2; + $$->vi_int[0] = $1.in_index; + } + ; + +leaving + : /* empty */ + { $$ = 0; } + | LEAVING {emhere=1; } leavelist + { emhere=0; $$ = $3; } + ; +leavelist + : leavelist_el + | leavelist_el leavelist + { $$=$1; $$->vi_next=$2; } + ; +leavelist_el + : EMMNEM optexpr + { NEW($$,struct varinfo); + $$->vi_next=0; + $$->vi_int[0] = $1; + $$->vi_int[1] = $2; + } + ; + +optstring + : /* empty */ + { $$ = 0; } + | STRING + ; +optexpr + : /* empty */ + { $$ = 0; } + | expr + { $$ = $1.ex_index; } /* type checking ? */ + ; + +tokeninstance + : tokarg subreg + { $$ = subr_iocc($1,$2); } + | tokarg '.' IDENT + { $$ = tokm_iocc($1,$3); free($3); } + | IDENT + { $$ = ident_iocc($1); free($1);} + | allreg subreg + { $$ = all_iocc($1,$2); } + | '{' IDENT attlist '}' + { $$ = descr_iocc($2); free($2); } + ; +attlist + : /* empty */ + { narexpr = 0; } + | attlist ',' expr + { arexp[narexpr++] = $3; } + ; + +emarg + : DOLLAR + { if ($1<1 || $1>empatlen) + error("Only %d instructions in pattern",empatlen); + $$ = $1; + } + ; +tokarg + : PERCENT + { if ($1<1 || $1>tokpatlen) { + error("Only %d tokens in stackpattern",tokpatlen); + $$ =1; + } else { + $$ = $1; + } + } + ; +subreg + : /* empty */ + { $$ = 0; } + | '.' NUMBER + { if ($2<1 || $2>2) { + error("Only 2 subregisters allowed"); + $$ = 1; + } else { + $$ = $2; + } + } + ; +allreg + : ALLREG + { if ($1>=nallreg) + fatal("Only %d registers allocated",nallreg); + $$ = $1; + } + ; + +expr + : NUMBER + { $$ = make_expr(TYPINT,EX_CON, (int) ($1 & 0xFFFF), (int) ($1>>16)); + } + | emarg + { $$ = make_expr(argtyp(emmnem[$1-1]),EX_ARG,$1,0); } + | STRING + { $$ = make_expr(TYPADDR,EX_STRING,strlookup($1),0); free($1); } + | IDENT + { $$ = ident_expr($1); free($1); } + | tokarg subreg + { $$ = subreg_expr($1,$2); } + | tokarg '.' IDENT + { $$ = tokm_expr($1,$3); free($3); } + | allreg subreg + { $$ = all_expr($1,$2); } + | PERC_IDENT + { $$ = perc_ident_expr($1); free($1); } + | DEFINED '(' expr ')' + { $$ = make_expr(TYPBOOL,EX_DEFINED,i_expr($3),0); } + | SAMESIGN '(' expr ',' expr ')' + { $$ = make_expr(TYPBOOL,EX_SAMESIGN,i_expr($3),i_expr($5)); } + | SFIT '(' expr ',' expr ')' + { $$ = make_expr(TYPBOOL,EX_SFIT,i_expr($3),i_expr($5)); } + | UFIT '(' expr ',' expr ')' + { $$ = make_expr(TYPBOOL,EX_UFIT,i_expr($3),i_expr($5)); } + | ROM '(' emarg ',' NUMBER ')' + { $$ = make_expr(TYPINT,EX_ROM,$3-1,chkincl($5,1,3)-1); } + | LOWW '(' emarg ')' + { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); } + | HIGHW '(' emarg ')' + { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); } + | '(' expr ')' + { $$ = $2; } + | expr CMPEQ expr + { $$ = make_expr(TYPBOOL,eq2expr($1,$3),$1.ex_index,$3.ex_index); } + | expr CMPNE expr + { $$ = make_expr(TYPBOOL,ne2expr($1,$3),$1.ex_index,$3.ex_index); } + | expr CMPLT expr + { $$ = make_expr(TYPBOOL,EX_NCPLT,i_expr($1),i_expr($3)); } + | expr CMPGT expr + { $$ = make_expr(TYPBOOL,EX_NCPGT,i_expr($1),i_expr($3)); } + | expr CMPLE expr + { $$ = make_expr(TYPBOOL,EX_NCPLE,i_expr($1),i_expr($3)); } + | expr CMPGE expr + { $$ = make_expr(TYPBOOL,EX_NCPGE,i_expr($1),i_expr($3)); } + | expr OR2 expr + { $$ = make_expr(TYPBOOL,EX_OR2,b_expr($1),b_expr($3)); } + | expr AND2 expr + { $$ = make_expr(TYPBOOL,EX_AND2,b_expr($1),b_expr($3)); } + | expr '+' expr + { $$ = sum_expr($1,$3); } + | expr '-' expr + { $$ = make_expr(TYPINT,EX_MINUS,i_expr($1),i_expr($3)); } + | expr '*' expr + { $$ = make_expr(TYPINT,EX_TIMES,i_expr($1),i_expr($3)); } + | expr '/' expr + { $$ = make_expr(TYPINT,EX_DIVIDE,i_expr($1),i_expr($3)); } + | expr '%' expr + { $$ = make_expr(TYPINT,EX_MOD,i_expr($1),i_expr($3)); } + | expr LSHIFT expr + { $$ = make_expr(TYPINT,EX_LSHIFT,i_expr($1),i_expr($3)); } + | expr RSHIFT expr + { $$ = make_expr(TYPINT,EX_RSHIFT,i_expr($1),i_expr($3)); } + | NOT expr + { $$ = make_expr(TYPBOOL,EX_NOT,b_expr($2),0); } + | COMP expr + { $$ = make_expr(TYPINT,EX_COMP,i_expr($2),0); } + | INREG '(' expr ')' + { $$ = make_expr(TYPINT,EX_INREG,i_expr($3),0); } + | regvartype + { $$ = make_expr(TYPINT,EX_CON, $1+1, 0); } + | REGVAR '(' expr optregvartype ')' + { $$ = regvar_expr($3,$4); } + ; + +optregvartype + : /* empty */ + { $$ = reg_any; } + | ',' regvartype + { $$ = $2; } + ; +%% +#include "scan.c" diff --git a/util/ncgg/coerc.c b/util/ncgg/coerc.c new file mode 100644 index 000000000..b2ab826c2 --- /dev/null +++ b/util/ncgg/coerc.c @@ -0,0 +1,249 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "assert.h" +#include "param.h" +#include "set.h" +#include "property.h" +#include "reg.h" +#include "token.h" +#include "varinfo.h" +#include "iocc.h" +#include +#include "pseudo.h" +#include "extern.h" + +extern set_t l_sets[]; + +int nmoves; +move_t l_moves[MAXMOVES]; +short posmoves[MAXREGS+MAXTOKENS][SETSIZE]; + +n_move(s1,e1,s2,e2,vi) struct varinfo *vi; { + register move_p mp; + register i,j; + + NEXT(nmoves,MAXMOVES,"Moves"); + mp = &l_moves[nmoves-1]; + mp->m_set1 = s1; + mp->m_expr1 = e1; + mp->m_set2 = s2; + mp->m_expr2 = e2; + mp->m_cindex = codeindex; + dopattern(0,VI_NULL,VI_NULL,vi,VI_NULL,VI_NULL); + if (mp->m_expr1!=0 || mp->m_expr2!=0) + return; + for (i=0;im_set1].set_val,i)) + for(j=0;jm_set2].set_val[j]; +} + +existmove(from,sp) iocc_t from; short *sp; { + register i; + + for (i=0;ivi_int[0] = INSMOVE; + vp->vi_int[1] = from.in_index; + vp->vi_int[2] = to.in_index; + return(vp); +} + +int ntests; +test_t l_tests[MAXTESTS]; +short postests[SETSIZE]; + +n_test(s,e,vi) struct varinfo *vi; { + register test_p tp; + register i; + + NEXT(ntests,MAXTESTS,"Tests"); + tp = &l_tests[ntests-1]; + tp->t_set = s; + tp->t_expr = e; + tp->t_cindex = codeindex; + dopattern(0,VI_NULL,VI_NULL,vi,VI_NULL,VI_NULL); + if (tp->t_expr!=0) + return; + for(i=0;it_set].set_val[i]; +} + +struct varinfo *gen_test(from) iocc_t from; { + register struct varinfo *vp; + + if (!subset(from.in_set,postests,SETSIZE)) { + error("No such test"); + return(0); + } + NEW(vp,struct varinfo); + vp->vi_int[0] = INSTEST; + vp->vi_int[1] = from.in_index; + return(vp); +} + +struct varinfo *gen_preturn() { + register struct varinfo *vp; + + NEW(vp,struct varinfo); + vp->vi_int[0] = INSPRETURN; + return(vp); +} + +struct varinfo *gen_tlab(n) { + register struct varinfo *vp; + + assert(n>=0 && n<=9); + NEW(vp,struct varinfo); + vp->vi_int[0] = INSTLAB; + vp->vi_int[1] = n; + return(vp); +} + +int nstacks; +c1_t l_stacks[MAXSTACKS]; +set_t ustackset,cstackset; + +n_stack(s,e,p,vi) struct varinfo *vi; { + register c1_p c1p; + register short *sp; + register i; + + NEXT(nstacks,MAXSTACKS,"Stacks"); + c1p= & l_stacks[nstacks-1]; + c1p->c1_texpno = s; + c1p->c1_expr = e; + c1p->c1_prop = p; + c1p->c1_codep = codeindex; + dopattern(0,VI_NULL,VI_NULL,vi,VI_NULL,VI_NULL); + + if (e==0 && p==0) + sp = ustackset.set_val; + else + sp = cstackset.set_val; + for(i=0;itk_name); +} + +int ncoercs; +c3_t l_coercs[MAXCOERCS]; +set_t unstackset; + +/*VARARGS5*/ + +n_coerc(ti,be,al,ge,rp,in) struct varinfo *al,*ge,*rp; iocc_t in; { + register c3_p c3p; + register i; + register struct varinfo *vi; + + if (ti!=0) { + for(i=0,vi=rp;vi!=0;vi=vi->vi_next,i++) + ; + if (i>1) { + n_split(ti,be,al,ge,rp,i); + return; + } else { + if (i==0) { + error("Coercion should have a result!"); + return; + } + } + } else { + NEW(rp,struct varinfo); + rp->vi_next = 0; + rp->vi_int[0] = in.in_index; + } + if (nallreg>1) + error("More than 1 register may not be allocated"); + NEXT(ncoercs,MAXCOERCS,"Coercions"); + c3p = & l_coercs[ncoercs-1]; + c3p->c3_texpno = ti; + c3p->c3_expr = be; + c3p->c3_prop = nallreg==0 ? 0 : allreg[0]; + c3p->c3_repl = rp->vi_int[0]; + c3p->c3_codep = codeindex; + dopattern(ti==0,VI_NULL,al,ge,rp,VI_NULL); + if (ti==0) + for(i=0;iMAXSPLIT) { + error("Maximum split factor is %d",MAXSPLIT); + n = MAXSPLIT; + } + if (n>maxsplit) maxsplit=n; + c2p->c2_texpno = ti; + c2p->c2_expr = be; + if (nallreg) + error("No register uses allowed in splitting coercion"); + c2p->c2_nsplit = n; + for (i=0,vi=rp; ivi_next) + c2p->c2_repl[i] = vi->vi_int[0]; + c2p->c2_codep = codeindex; + dopattern(0,VI_NULL,al,ge,rp,VI_NULL); +} diff --git a/util/ncgg/cvtkeywords b/util/ncgg/cvtkeywords new file mode 100755 index 000000000..31fc0b456 --- /dev/null +++ b/util/ncgg/cvtkeywords @@ -0,0 +1,22 @@ +: '$Header$' +grep '^#' y.tab.h >tokendefs +ed - keywords <<'!Funky!Stuff!' +g/^#/d +1,$s/\([^ ]*\)[ ][ ]*\(.*\)/ sy_p=lookup("\1",symkeyw,newsymbol);sy_p->sy_value.syv_keywno=\2;/ +1i +#include "lookup.h" +. +.r tokendefs +a + +enterkeyw() { + register symbol *sy_p; + +. +$a +} +. +w enterkeyw.c +q +!Funky!Stuff! +rm tokendefs diff --git a/util/ncgg/emlookup.c b/util/ncgg/emlookup.c new file mode 100644 index 000000000..85289a772 --- /dev/null +++ b/util/ncgg/emlookup.c @@ -0,0 +1,73 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "param.h" +#include "expr.h" +#include +#include + +extern char em_mnem[][4]; + +#define HASHSIZE (2*(sp_lmnem-sp_fmnem)) + +struct emhashmnem { + char h_name[3]; + char h_value; +} emhashmnem[HASHSIZE]; + +initemhash() { + register i; + + for(i=0;i<=sp_lmnem-sp_fmnem;i++) + enter(em_mnem[i],i+sp_fmnem); +} + +unsigned emhash(name) register char *name; { + register unsigned sum; + register i; + + for (sum=i=0;*name;i+=3) + sum ^= (*name++)<<(i&07); + return(sum); +} + +enter(name,value) char *name; { + register unsigned h; + + h=emhash(name)%HASHSIZE; + while (emhashmnem[h].h_name[0] != 0) + h = (h+1)%HASHSIZE; + strncpy(emhashmnem[h].h_name,name,3); + emhashmnem[h].h_value = value; +} + +int mlookup(name) char *name; { + register unsigned h; + + h = emhash(name)%HASHSIZE; + while (strncmp(emhashmnem[h].h_name,name,3) != 0 && + emhashmnem[h].h_name[0] != 0) + h = (h+1)%HASHSIZE; + return(emhashmnem[h].h_value&0xFF); /* 0 if not found */ +} + +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(TYPADDR); + } +} diff --git a/util/ncgg/error.c b/util/ncgg/error.c new file mode 100644 index 000000000..c3bf854d8 --- /dev/null +++ b/util/ncgg/error.c @@ -0,0 +1,54 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include + +int nerrors=0; + +yyerror(s) char *s; { + + error("Parser gives %s",s); +} + +goodbye() { + + error("This was fatal, goodbye!"); +#ifndef NDEBUG + abort(); +#endif +} + +/*VARARGS1*/ +fatal(s,a,b,c,d) char *s; { + + error(s,a,b,c,d); + errorexit(); + goodbye(); + exit(-1); +} + +/*VARARGS1*/ +error(s,a,b,c,d) char *s; { + extern int lineno; + extern char *filename; + + fprintf(stderr,"\"%s\", line %d:",filename,lineno); + fprintf(stderr,s,a,b,c,d); + fprintf(stderr,"\n"); + nerrors++; +} + +#ifndef NDEBUG +badassertion(string,file,line) char *string,*file; { + + fprintf(stderr,"\"%s\", line %d: Assertion failed \"%s\"\n", + file,line,string); + goodbye(); +} +#endif + +tabovf(string) char *string; { + + fatal("%s overflow",string); +} diff --git a/util/ncgg/expr.c b/util/ncgg/expr.c new file mode 100644 index 000000000..77dd1a09b --- /dev/null +++ b/util/ncgg/expr.c @@ -0,0 +1,311 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "assert.h" +#include "param.h" +#include "set.h" +#include "reg.h" +#include "lookup.h" +#include "token.h" +#include "property.h" +#include "expr.h" +#include "regvar.h" +#include +#include "extern.h" + +extern set_t l_sets[]; + +i_expr(e) expr_t e; { + + if (e.ex_typ != TYPINT) + error("Expression should be integer"); + return(e.ex_index); +} + +b_expr(e) expr_t e; { + if (e.ex_typ != TYPBOOL) + error("Expression should be boolean"); + return(e.ex_index); +} + +expr_t make_expr(type,operator,op1,op2) { + expr_t result; + + result.ex_typ=type; + result.ex_index=ex_lookup(operator,op1,op2); + return(result); +} + +expr_t regno_expr(regno) { + expr_t result; + register i; + + result.ex_typ = TYPREG; + result.ex_index = ex_lookup(EX_REG,regno,0); + for (i=0;isy_type==symconst) + return(make_expr(TYPINT,EX_CON, + (int) (sy_p->sy_value.syv_cstval&0xFFFF), + (int) (sy_p->sy_value.syv_cstval>>16))); + else if (sy_p->sy_type==symsconst) + return(make_expr(TYPADDR,EX_STRING,sy_p->sy_value.syv_stringno,0)); + else if (sy_p->sy_type!=symreg) + error("Wrong type of identifier %s",name); + return(regno_expr(sy_p->sy_value.syv_regno)); +} + +expr_t subreg_expr(tokarg,subreg) { + expr_t result; + + result.ex_typ = TYPREG; + subregset(l_sets[tokpatset[tokarg-1]].set_val,subreg,result.ex_regset); + result.ex_index = ex_lookup(EX_SUBREG,tokarg,subreg); + return(result); +} + +subregset(sp,subreg,regset) register short *sp; register short *regset; { + register i; + register reginfo *rp; + + for (i=0;iri_memb[subreg-1]==0) + error("Register %s in set has no member %d", + rp->ri_name,subreg); + BIS(regset,rp->ri_memb[subreg-1]); + } else + BIS(regset,i); + } + for(;itk_name); +} + +membset(setno,name,regset,appearance,restyp,typp) +char *name,*appearance; +short *regset; +int *typp; +{ + register short *sp; + register token_p tp; + register i,j,k; + int thistyp; + int typesdiffer=0; + int res_j= -1; + + sp = l_sets[setno].set_val; + for (i=1;itk_att[j].ta_type == -3 || + strcmp(tp->tk_att[j].ta_name,name));j++) + ; + if (j==MAXATT) + error("Token %s does not contain %s",tp->tk_name,name); + else if (j!=res_j && res_j != -1) + typesdiffer=1; + else { + res_j = j; + thistyp = tp->tk_att[j].ta_type; + if (thistyp== -2) { + if (restyp!=TYPADDR && restyp!=0) + typesdiffer=1; + else + restyp=TYPADDR; + } else if (thistyp== -1) { + if (restyp!=TYPINT && restyp!=0) + typesdiffer=1; + else + restyp=TYPINT; + } else { + if (restyp!=TYPREG && restyp!=0) + typesdiffer=1; + else { + restyp=TYPREG; + for(k=0;ktk_att[j].ta_type].pr_regset[k]; + } + } + } + } + if (typesdiffer) + error("%s is not a valid expression; types differ in the set", + appearance); + *typp = restyp==0 ? TYPINT : restyp; + return(res_j == -1 ? 0 : res_j); +} + +expr_t memb_expr(setno,name,appearance,tokarg) char *name,*appearance; { + expr_t result; + int res_j; + + res_j = membset(setno,name,result.ex_regset,appearance,0,&result.ex_typ); + result.ex_index = ex_lookup(EX_TOKFIELD,tokarg,res_j+1); + return(result); +} + +expr_t tokm_expr(tokarg,name) char *name; { + char app[100]; + + sprintf(app,"%%%d.%s",tokarg,name); + return(memb_expr(tokpatset[tokarg-1],name,app,tokarg)); +} + +expr_t perc_ident_expr(name) char *name; { + char app[100]; + + sprintf(app,"%%%s",name); + return(memb_expr(cursetno,name,app,0)); +} + +expr_t all_expr(all_no,subreg) { + set_t localset; + register i; + register short *sp; + expr_t result; + + sp = l_props[allreg[all_no]].pr_regset; + for (i=0;iex_operator != operator) + continue; + if (p->ex_lnode != lnode) + continue; + if (p->ex_rnode != rnode) + continue; + return(p-nodes); + } + NEXT(nnodes,MAXNODES,"Node"); + p->ex_operator = operator; + p->ex_lnode = lnode; + p->ex_rnode = rnode; + return(p-nodes); +} diff --git a/util/ncgg/hall.c b/util/ncgg/hall.c new file mode 100644 index 000000000..94eb5504a --- /dev/null +++ b/util/ncgg/hall.c @@ -0,0 +1,155 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "assert.h" +#include "param.h" +#include "set.h" +#include + +/* + * This file implements the marriage thesis from Hall. + * The thesis says that given a number, say N, of subsets from + * a finite set, it is possible to create a set with cardinality N, + * that contains one member for each of the subsets, + * iff for each number, say M, of subsets from 2 to N the union of + * each M-tuple sets has cardinality >= M. + * + * So what, you might say. As indeed I did. + * But this is actually used here to check the possibility of each + * code rule. If a code rule has a number of token_sets in the with + * clause and a number of properties in the uses rule it must be + * possible to do this from an empty fakestack. Hall helps. + */ + +#define MAXHALL (TOKPATMAX+MAXALLREG) +short hallsets[MAXHALL][SETSIZE]; +int nhallsets= -1; +int hallfreq[MAXHALL][2]; + +hallverbose() { + register i; + register max; + + fprintf(stderr,"Table of hall frequencies\n # pre post\n"); + for (max=MAXHALL-1;hallfreq[max][0]==0 && hallfreq[max][1]==0;max--) + ; + for (i=0;i<=max;i++) + fprintf(stderr,"%3d%6d%6d\n",i,hallfreq[i][0],hallfreq[i][1]); +} + +inithall() { + + assert(nhallsets == -1); + nhallsets=0; +} + +nexthall(sp) register short *sp; { + register i; + + assert(nhallsets>=0); + for(i=0;i=0); + if (!hall()) + error("Hall says: \"You can't have those registers\""); +} + +hall() { + register i,j,k; + int ok; + + hallfreq[nhallsets][0]++; + /* + * If a set has cardinality >= nhallsets it can never be the cause + * of the hall algorithm failing. So it can be thrown away. + * But then nhallsets is less, so this step can be re-applied. + */ + + do { + ok = 0; + for(i=0;i=nhallsets) { + for (j=i+1;j +#include "extern.h" + +extern int niops; +extern iocc_t iops[]; +extern inproc; + +extern set_t l_sets[]; +extern inst_t l_instances[]; + +extern expr_t subreg_expr(),regno_expr(); + +struct varinfo * setcoco(n) { + struct varinfo *vi; + + NEW(vi,struct varinfo); + vi->vi_next = VI_NULL; + vi->vi_int[0] = INSSETCC; + vi->vi_int[1] = n; + return(vi); +} + +struct varinfo * generase(n) { + struct varinfo *vi; + + NEW(vi,struct varinfo); + vi->vi_next = VI_NULL; + vi->vi_int[0] = INSERASE; + vi->vi_int[1] = n; + return(vi); +} + +onlyreg(argno) { + register bitno; + register short *sp; + + sp = l_sets[tokpatset[argno-1]].set_val; + for(bitno=nregs;bitnoi_name)) + continue; + if (ip->i_nops!=niops) + continue; + for(i=0,op=ip->i_oplist;io_next) { + if (!subset(iops[i].in_set,l_sets[op->o_setno].set_val,SETSIZE)) + goto cont; + } + goto found; /* oh well, one more won't hurt */ + cont:; + } + error("Such an \"%s\" does not exist",ident); + return(0); +found: + NEW(vi,struct varinfo); + vi->vi_int[0] = ip-l_instr; + vi->vi_int[1] = star; + vi->vi_next=0; + retval = vi; + for(i=0;ivi_vi,struct varinfo); + vi=vi->vi_vi; + vi->vi_int[0] = iops[i].in_index; + } + vi->vi_vi = 0; + vi = retval; + for(i=0,op=ip->i_oplist;io_next) { + if(op->o_adorn&AD_CC) { + vi->vi_next = setcoco(iops[i].in_index); + vi=vi->vi_next; + } + switch(op->o_adorn&AD_RWMASK) { + default: + /* Nothing possible to do */ + break; + case AD_RO: + /* It might be possible to do something + * here but not now. + */ + break; + case AD_RW: + case AD_WO: + /* Treated the same for now */ + insta = &l_instances[iops[i].in_index]; + switch(insta->in_which) { + case IN_COPY: + if(insta->in_info[1]==0 && !onlyreg(insta->in_info[0])) + break; + makescratch(insta->in_info[0]); + vi->vi_next = generase( + ex_lookup( + EX_SUBREG,insta->in_info[0], + insta->in_info[1] + ) + ); + vi = vi->vi_next; + break; + case IN_MEMB: + vi->vi_next = generase( + ex_lookup( + EX_TOKFIELD,insta->in_info[0], + insta->in_info[1] + ) + ); + vi=vi->vi_next; + break; + case IN_RIDENT: + vi->vi_next = generase( + ex_lookup( + EX_REG,insta->in_info[0],0 + ) + ); + vi = vi->vi_next; + break; + case IN_ALLOC: + vi->vi_next = generase( + ex_lookup( + EX_ALLREG,insta->in_info[0]+1, + insta->in_info[1] + ) + ); + vi = vi->vi_next; + break; + case IN_S_DESCR: + case IN_D_DESCR: + vi->vi_next = generase( + ex_lookup( + EX_REGVAR,insta->in_info[1],0 + ) + ); + vi = vi->vi_next; + break; + } + break; + } + } + for (eravi=ip->i_erases;eravi != VI_NULL;eravi=eravi->vi_next) { + if (eravi->vi_int[0] < 0) + vi->vi_next = setcoco(0); + else + vi->vi_next = generase(eravi->vi_int[0]); + vi=vi->vi_next; + } + return(retval); +} diff --git a/util/ncgg/iocc.c b/util/ncgg/iocc.c new file mode 100644 index 000000000..357c644bb --- /dev/null +++ b/util/ncgg/iocc.c @@ -0,0 +1,187 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "assert.h" +#include "param.h" +#include "set.h" +#include "expr.h" +#include "lookup.h" +#include "token.h" +#include "property.h" +#include "iocc.h" +#include +#include "regvar.h" +#include "extern.h" + +extern set_t l_sets[]; + +int narexpr; +expr_t arexp[MAXATT]; + +expr_t iextoaddr(); + +iocc_t subr_iocc(tokarg,subreg) { + inst_t insta; + iocc_t result; + register i; + + insta.in_which = IN_COPY; + insta.in_info[0] = tokarg; + insta.in_info[1] = subreg; + result.in_index = instalookup(insta,2); + if (subreg==0) + for (i=0;isy_value.syv_regno; + result.in_index = instalookup(insta,1); + BIS(result.in_set,sy_p->sy_value.syv_regno); + return(result); +} + +iocc_t all_iocc(all_no,subreg) { + iocc_t result; + inst_t insta; + register i; + set_t localset; + register short *sp; + + sp = l_props[allreg[all_no]].pr_regset; + for (i=0;isy_value.syv_tokno]; + BIS(result.in_set,sy_p->sy_value.syv_tokno+nregs); + insta.in_which = IN_DESCR; + if (rvused&SL_REGVAR && strcmp(ident,"LOCAL")==0) + insta.in_which = IN_S_DESCR; + else if (rvused&DL_REGVAR && strcmp(ident,"DLOCAL")==0) + insta.in_which = IN_D_DESCR; + insta.in_info[0] = sy_p->sy_value.syv_tokno; + for (i=0;itk_att[i].ta_type == -3) { + if (narexpr>i) + error("token %s initialized with too many attributes",ident); + break; + } + if (i>= narexpr) { + error("token %s initialized with too few attributes", + ident); + break; + } + typerr = 0; + switch(arexp[i].ex_typ) { + default: assert(0); + case TYPINT: + if (tp->tk_att[i].ta_type != -1) + if (tp->tk_att[i].ta_type == -2) + arexp[i] = iextoaddr(arexp[i]); + else + typerr++; + break; + case TYPBOOL: + typerr++; break; + case TYPADDR: + if (tp->tk_att[i].ta_type != -2) + typerr++; + break; + case TYPREG: + if (tp->tk_att[i].ta_type<0) + typerr++; + else if (!subset(arexp[i].ex_regset, + l_props[tp->tk_att[i].ta_type].pr_regset, + SZOFSET(MAXREGS))) + typerr++; + break; + } + if (typerr) + error("Attribute %s.%s given wrong type of value", + ident,tp->tk_att[i].ta_name); + insta.in_info[i+1] = arexp[i].ex_index; + } + result.in_index = instalookup(insta,i+1); + return(result); +} + +/* low level instance package */ + +int ninstances=1; +inst_t l_instances[MAXINSTANCES]; + +instalookup(insta,filled) inst_t insta; { + register i,j; + + for (j=filled;j<=MAXATT;j++) + insta.in_info[j] = 0; + for (i=0;isy_next) { + if (strcmp(sy_p->sy_name,name)!=0) + continue; + switch(style) { + default: + assert(0); + case justlooking: + case mustexist: + case makeexist: + if (type==symany || type==sy_p->sy_type) + return(sy_p); + continue; + case newsymbol: + error("%s already defined",name); + return(&dumsym); + } + } + switch(style) { + default: + assert(0); + case justlooking: + return((symbol *) 0); + case mustexist: + fatal("%s is unknown symbol",name); + /* NOTREACHED */ + case newsymbol: + case makeexist: + NEW(sy_p,symbol); + sy_p->sy_next = 0; + sy_p->sy_name = mystrcpy(name); + assert(type!=symany); + sy_p->sy_type = type; + *sy_pp = sy_p; + return(sy_p); + } +} + +hashvalue(s) register char *s; { + register unsigned sum=0; + register i; + + for(i=0;*s;s++,i=(i+3)&07) + sum += *s< + +char *filename; + +main(argc,argv) char **argv; { + extern int nerrors; + extern int code_in_c; + extern int tabledebug; + extern int verbose; + + while (argc >1 && argv[1][0]=='-') { + switch(argv[1][1]) { + case 'c': + code_in_c = 0; + break; + case 'd': + tabledebug++; + break; + case 'v': + verbose++; + break; + default: + error("Unknown flag -%c",argv[1][1]); + } + argc--; argv++; + } + if (argc==2) { + if (freopen(argv[1],"r",stdin)==NULL) { + error("Can't open %s",argv[1]); + exit(-1); + } + filename = argv[1]; + } else + error("Usage: %s [-c] [-d] [-v] table",argv[0]); + initemhash(); + enterkeyw(); + initnodes(); + initio(); + yyparse(); + if (nerrors==0) { + finishio(); + statistics(); + if (verbose) + hallverbose(); + } else { + errorexit(); + } + return(nerrors==0 ? 0 : -1); +} diff --git a/util/ncgg/makedepend b/util/ncgg/makedepend new file mode 100755 index 000000000..31e2e20da --- /dev/null +++ b/util/ncgg/makedepend @@ -0,0 +1,15 @@ +: '$Header$' +for extension in c y +do + for file in *.$extension + do ofile=`basename $file .$extension`.o + grep '^# *include.*"' $file|sed "s/.*\"\(.*\)\".*/$ofile: \1/" + done +done | sort -u >depend +ed - Makefile <<'!' +/AUTOAUTOAUTO/+,$d +$r depend +w +q +! +rm -f depend diff --git a/util/ncgg/output.c b/util/ncgg/output.c new file mode 100644 index 000000000..7dbf5f3e2 --- /dev/null +++ b/util/ncgg/output.c @@ -0,0 +1,837 @@ +/* #define CODEDEBUG /* print readable code */ +#ifdef CODEDEBUG +int code_in_c=0; /* put readable code in "code" */ +int tabledebug=1; /* generate code for table debugging */ +#else +int code_in_c=1; /* put code in "tables.c" */ +int tabledebug=0; /* do not generate code for table debugging */ +#endif +int verbose=0; /* print all statistics */ +char *c_file= "tables.c"; +char *h_file= "tables.H"; +char *cd_file= "code"; + +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include +#include +#include "assert.h" +#include "varinfo.h" +#include "param.h" +#include "reg.h" +#include "property.h" +#include "token.h" +#include "set.h" +#include "instruct.h" +#include "lookup.h" +#include +#include "pseudo.h" +#include "regvar.h" +#include "extern.h" + +#define BMASK 0xFF +#define BSHIFT 8 + +FILE *ctable,*htable; +FILE *code; +short *lineset; +int maxline; + +extern int nstrings; +extern char *l_strings[]; + +extern int ninstances; +extern inst_t l_instances[]; + +extern int nmoves; +extern move_t l_moves[]; +extern int ntests; +extern test_t l_tests[]; +extern int nstacks; +extern c1_t l_stacks[]; +extern int ncoercs; +extern c3_t l_coercs[]; +extern int nsplit,maxsplit; +extern c2_t l_split[]; +extern set_t l_sets[]; + +int maxallreg=0; +int maxregvars=0; +int setsize; + +opnfile(f,s) FILE **f; char *s; { + + if ((*f=fopen(s,"w"))==NULL) + fatal("Can't create %s",s); +} + +unlfile(f,s) FILE *f; char *s; { + + fclose(f); + if (unlink(s)<0) + error("%s incorrect, must be removed!!",s); +} + +initio() { + extern char *myalloc(); + + opnfile(&ctable,c_file); + opnfile(&htable,h_file); + if (code_in_c) + fprintf(ctable,"char coderules[] = {"); + else + opnfile(&code,cd_file); + patbyte(0); + if (tabledebug) + lineset = (short *) myalloc(SZOFSET(MAXSOURCELINES)*sizeof(short)); +} + +finishcode() { + + if (code_in_c) + fprintf(ctable,"\n};\n\n"); + if (tabledebug) { + int fd; + int sz; + + if ((fd=creat("lineset",0666))>=0) { + sz = SZOFSET(maxline)*2; + write(fd,&sz,sizeof(int)); + write(fd,lineset,sz); + close(fd); + } else + error("Can't create lineset"); + } +} + +errorexit() { + + unlfile(ctable,c_file); + unlfile(htable,h_file); + if (!code_in_c) + unlfile(code,cd_file); +} + +#ifdef CODEDEBUG +#define code8(x) fprintf(code,"%s","x") +#define code8nl(x) fprintf(code,"%s\n","x") +#define code53(x,y) fprintf(code,"%s-%d","x",y) +#define codeint(x) fprintf(code," %d",x) +#define codenl() fprintf(code,"\n") +#else +code8(x) { + + codeindex++; + if (code_in_c) + fprintf(ctable,"%d,",x&0377); + else + putc(x,code); +} + +code8nl(x) { + + code8(x); +} + +code53(x,y) { + + code8(x+(y<<5)); +} + +codeint(x) { + + assert(x>=0 && x<=32767); + if (x<128) { + code8(x); + } else { + code8(x/256+128); + code8(x%256); + } +} + +codenl() { +} +#endif +int prevind=0; +int npatbytes=0; +char pattern[MAXPATBYTES]; +int pathash[256]; + +outpatterns() { + extern int npatterns; + extern int patindex[]; + extern int empatlen; + extern int emmnem[]; + extern int empatexpr; + register i; + + if (!inproc) { + patbyte(0); + patshort(prevind); + prevind = npatbytes-3; + patbyte(empatlen); + for(i=0;i=0); + if (n<128) + patbyte(n); + else { + patbyte(n/256+128); + patbyte(n%256); + } +} + +patshort(n) { + + patbyte(n%256); + patbyte(n/256); +} + +patbyte(n) { + + pattern[npatbytes++]=n; +} + +hashpatterns() { + short index; + register char *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; + } +} + +outincludes() { + + fprintf(ctable,"#include \"param.h\"\n"); + fprintf(ctable,"#include \"tables.h\"\n"); + fprintf(ctable,"#include \"types.h\"\n"); + fprintf(ctable,"#include \n"); + fprintf(ctable,"#include \"data.h\"\n"); +} + +outregs() { + register i,j,k; + short rset[SZOFSET(MAXREGS)]; + int t,ready; + + + fprintf(ctable,"char stregclass[] = {\n"); + for (i=0;i=0); + fprintf(ctable,"},\n"); + } + fprintf(ctable,"};\n\n"); +} + +outregvars() { + register i,j; + + fprintf(htable,"#define REGVARS\n"); + fprintf(ctable,"#include \"regvar.h\"\n"); + fprintf(ctable,"int nregvar[4] = { "); + for (i=0;i<4;i++) { + fprintf(ctable,"%d, ",nregvar[i]); + if (nregvar[i]>maxregvars) + maxregvars = nregvar[i]; + } + fprintf(ctable,"};\n"); + for (i=0;i<4;i++) + if (nregvar[i]>0) + fprintf(ctable,"struct regassigned ratar%d[%d];\n", + i,nregvar[i]); + for (i=0;i<4;i++) if (nregvar[i]>0) { + fprintf(ctable,"int rvtar%d[] = {",i); + for (j=0;j0) + fprintf(ctable,"\trvtar%d,\n",i); + else + fprintf(ctable,"\t0,\n"); + fprintf(ctable,"};\n\nstruct regassigned *regassigned[] = {\n"); + for (i=0;i<4;i++) + if (nregvar[i]>0) + fprintf(ctable,"\tratar%d,\n",i); + else + fprintf(ctable,"\t0,\n"); + fprintf(ctable,"};\n"); +} + +typeconv(n) { + + if (n>=0) return(2); + if (n== -1) return(1); + if (n== -2) return(3); + assert (n== -3); + return(0); +} + +outtokens() { + register tokno,i; + register token_p tp; + + fprintf(ctable,"tkdef_t tokens[] = {{0},\n"); + for (tokno=1;toknotk_size, tp->tk_cost.ct_space, tp->tk_cost.ct_time); + for(i=0;itk_att[i].ta_type)); + fprintf(ctable,"},%d},\n",tp->tk_format); + } + fprintf(ctable,"{0}};\n\n"); +} + +outenodes() { + register node_p np; + extern node_t nodes[]; + extern int nnodes; + + fprintf(ctable,"node_t enodes[] = {\n"); + for (np=nodes;np<&nodes[nnodes];np++) + fprintf(ctable,"{%d,%d,%d},\n", + np->ex_operator,np->ex_lnode,np->ex_rnode); + fprintf(ctable,"};\n\n"); +} + +outstrings() { + register i; + register char *p,c; + extern char * filename; + + if (tabledebug) + fprintf(ctable,"char *tablename = \"%s\";\n",filename); + fprintf(ctable,"string codestrings[] = {\n"); + for(i=0;iset_size); + for (i=0;iset_val[i]&0xFFFF); + fprintf(ctable,"}},\n"); + } + fprintf(ctable,"};\n\n"); +} + +outinstances() { + register inst_p ip; + register i; + + fprintf(ctable,"inst_t tokeninstances[] = {\n"); + for (ip=l_instances;ip< &l_instances[ninstances]; ip++) { + fprintf(ctable,"{ %d, {",ip->in_which); + for(i=0;i<=maxtokensize;i++) + fprintf(ctable,"%d,",ip->in_info[i]); + fprintf(ctable,"}},\n"); + } + fprintf(ctable,"};\n\n"); +} + +outmoves() { + register move_p mp; + + fprintf(ctable,"move_t moves[] = {\n"); + for (mp=l_moves; mp< &l_moves[nmoves]; mp++) + fprintf(ctable,"{%d,%d,%d,%d,%d},\n", + mp->m_set1, mp->m_expr1, + mp->m_set2, mp->m_expr2, + mp->m_cindex); + fprintf(ctable,"{-1}\n};\n\n"); +} + +outtests() { + register test_p tp; + + fprintf(ctable,"test_t tests[] = {\n"); + for (tp=l_tests; tp< &l_tests[ntests]; tp++) + fprintf(ctable,"{%d,%d,%d},\n", + tp->t_set, tp->t_expr, + tp->t_cindex); + fprintf(ctable,"{-1}\n};\n\n"); +} + +outstacks() { + register c1_p cp; + + fprintf(ctable,"c1_t c1coercs[] = {\n"); + for (cp=l_stacks; cp< &l_stacks[nstacks]; cp++) + fprintf(ctable,"{%d,%d,%d,%d},\n", + cp->c1_texpno, cp->c1_expr, + cp->c1_prop, cp->c1_codep); + fprintf(ctable,"{-1}\n};\n\n"); +} + +outsplits() { + register c2_p cp; + register i; + + fprintf(ctable,"c2_t c2coercs[] = {\n"); + for (cp=l_split; cp< &l_split[nsplit]; cp++) { + fprintf(ctable,"{%d,%d,%d,{", + cp->c2_texpno, cp->c2_expr, cp->c2_nsplit); + for (i=0;ic2_repl[i]); + fprintf(ctable,"},%d},\n",cp->c2_codep); + } + fprintf(ctable,"{-1}\n};\n\n"); +} + +outcoercs() { + register c3_p cp; + + fprintf(ctable,"c3_t c3coercs[] = {\n"); + for (cp=l_coercs; cp< &l_coercs[ncoercs]; cp++) + fprintf(ctable,"{%d,%d,%d,%d,%d},\n", + cp->c3_texpno, cp->c3_expr, + cp->c3_prop, cp->c3_repl, cp->c3_codep); + fprintf(ctable,"{-1}\n};\n\n"); +} + +outproplists() { + register propno; + register regno; + + for(propno=0;propnosy_value.syv_stringno]; + else if (wordsize<=2) + wrdfmt = "%d"; + else + wrdfmt = "%ld"; + fprintf(ctable,"char wrd_fmt[]= \"%s\";\n", wrdfmt); + fprintf(htable,"#define WRD_FMT wrd_fmt\n"); + fprintf(htable,"extern char wrd_fmt[];\n"); + cdef("MAXALLREG",maxallreg); + cdef("SETSIZE",setsize); + cdef("NREGS",nregs); + cdef("REGSETSIZE",SZOFSET(nregs)); + cdef("TOKENSIZE",maxtokensize); + cdef("MAXMEMBERS",maxmembers); + cdef("LONGESTPATTERN",maxempatlen); + cdef("MAXRULE",maxrule<16 ? 16 : maxrule); + if (nsplit>0) { + cdef("MAXSPLIT",maxsplit); + } + if (tabledebug) + cdef("TABLEDEBUG",1); +} + +outars() { + register i; + + if (code_in_c) + fprintf(htable,"#define CODEINC 1\n"); + else { + fprintf(ctable,"char coderules[%d];\n",codeindex); + fprintf(ctable,"int ncodebytes=%d;\n",codeindex); + } + fprintf(ctable,"char pattern[%d]={\n",npatbytes); + for(i=0;i0) + outsplits(); + outcoercs(); + outproplists(); + outconsts(); + if (rvused) + outregvars(); + outars(); +} + +codecoco(cocono) { + + if (cocono== -1) + return; + code8(DO_SETCC); + codeint(cocono); + codenl(); +} + +dopattern(stackcoerc,kills,allocates,generates,yields,leaving) +varinfo *kills,*allocates,*generates,*yields,*leaving; +{ + register i; + int n,nops; + register struct varinfo *vp,*vivp; + register instr_p instp; + int al,deal; + int vil; + int cocono= -1; + cost_t totcost; + static char tlab[] = "0:"; + extern int optexact,optstack,startline; + extern char *filename; + extern int lineno; + +#ifdef CODEDEBUG + fprintf(code,"Code(%d) at \"%s\", line %d\n",stackcoerc,filename,lineno); +#endif + if (code_in_c) + fprintf(ctable,"\n/* \"%s\", line %d */ ",filename,lineno); + if (tabledebug) { + code8(DO_DLINE); + codeint(startline); + codenl(); + if (startlinemaxline) + maxline=startline; + BIS(lineset,startline); + } else { + static int beenhere=0; + + if (!beenhere) { + beenhere++; + error("Too many source lines for table debug"); + } + } + } + /* MATCH part */ + if (tokpatlen) { + if (optexact) + if (optstack) + code53(DO_XXMATCH,tokpatlen); + else + code53(DO_XMATCH,tokpatlen); + else + code53(DO_MATCH,tokpatlen); + for (i=0;ivi_next) { + if (vp->vi_int[1] != 0) { + code53(DO_REMOVE,1); + codeint(vp->vi_int[0]); + codeint(vp->vi_int[1]); + codenl(); + } else { + code53(DO_REMOVE,0); + codeint(vp->vi_int[0]); + codenl(); + } + } + /* allocate part */ + deal=0;al=0; + for (vp=allocates;vp!=0;vp=vp->vi_next) { + if (vp->vi_int[0] == -1) { /* Deallocate */ + deal++; + code8(DO_DEALLOCATE); + codeint(vp->vi_int[1]); + codenl(); + } else { + if (vp->vi_int[1]==0) { + code53(DO_ALLOCATE,0); + codeint(vp->vi_int[0]); + codenl(); + } else { + code53(DO_ALLOCATE,1); + codeint(vp->vi_int[0]); + codeint(vp->vi_int[1]); + codenl(); + } + al++; + } + } + if (deal) + code8nl(DO_REALLOCATE); + if (al>maxallreg) + maxallreg=al; + totcost.ct_space = 0; + totcost.ct_time = 0; + for(vp=generates;vp!=0;vp=vp->vi_next) { + n= vp->vi_int[0]; + switch(n) { + default: + assert(n>=0); + instp = &l_instr[n]; + nops=instp->i_nops; + code53(DO_INSTR,nops); + if (vp->vi_int[1]==0) { + codeint(instp->i_asname); + } else { + codeint(10000+vp->vi_int[1]); + } + vivp=vp->vi_vi; + for(i=0;ivi_int[0]); + vivp = vivp->vi_vi; + } + codenl(); + totcost.ct_space += instp->i_cost.ct_space; + totcost.ct_time += instp->i_cost.ct_time ; + break; + case INSMOVE: + codecoco(cocono); + code8(DO_MOVE); + codeint(vp->vi_int[1]); + codeint(vp->vi_int[2]); + codenl(); + break; + case INSTEST: + codecoco(cocono); + code8(DO_TEST); + codeint(vp->vi_int[1]); + codenl(); + break; + case INSPRETURN: + code8(DO_PRETURN); + codenl(); + break; + case INSTLAB: + tlab[0] = vp->vi_int[1] + '0'; + code53(DO_INSTR,0); + codeint(strlookup(tlab)); + codenl(); + break; + case INSSETCC: + cocono=vp->vi_int[1]; + break; + case INSERASE: + code8(DO_ERASE); + codeint(vp->vi_int[1]); + codenl(); + break; + } + } + codecoco(cocono); + vil = vilength(yields); + if (vil!=0 || tokpatlen!=0 || allocates!=0) { + code53(DO_TOKREPLACE,vilength(yields)); + for(vp=yields;vp!=0;vp=vp->vi_next) { + codeint(vp->vi_int[0]); + } + codenl(); + } + if (leaving!=0) { + code53(DO_EMREPLACE,vilength(leaving)); + while (leaving!=0) { + codeint(leaving->vi_int[0]); + codeint(leaving->vi_int[1]); + leaving = leaving->vi_next; + } + codenl(); + } + if (totcost.ct_space!=0 || totcost.ct_time!=0) { + code8(DO_COST); + codeint(totcost.ct_space); + codeint(totcost.ct_time); + codenl(); + } + if (empatlen==0 && !inproc) + code8nl(DO_RETURN); + else + code8nl(DO_NEXTEM); +} + +used(resource,use,max) char *resource; { + + if (verbose || 4*use > 3*max) + fprintf(stderr,"%s %d(%d)\n",resource,use,max); +} + +statistics() { + extern char *end,*sbrk(); + + used("Registers",nregs,MAXREGS); + used("Properties",nprops,MAXPROPS); + used("Tokens",ntokens,MAXTOKENS); + used("Tokensize",maxtokensize,MAXATT); + used("Sets",nsets,MAXSETS); + used("Instructions",ninstr,MAXINSTR); + used("Strings",nstrings,MAXSTRINGS); + used("Exp-nodes",nnodes,MAXNODES); + used("EM-pat length",maxempatlen,EMPATMAX); + used("rules/EM-pattern",maxrule,MAXPATTERNS); + used("Allocates/rule",maxallreg,MAXALLREG); + used("Instances",ninstances,MAXINSTANCES); + used("Moves",nmoves,MAXMOVES); + used("Tests",ntests,MAXTESTS); + used("Stacks",nstacks,MAXSTACKS); + used("1->1 Coercions",ncoercs,MAXCOERCS); + used("Splitting coercions",nsplit,MAXSPLCOERC); + used("Register variables",maxregvars,MAXREGVAR); + used("Pat bytes",npatbytes,MAXPATBYTES); + if (tabledebug) + used("Source lines",maxline,MAXSOURCELINES); + fprintf(stderr,"%ldK heap used\n",((long) (sbrk(0)-end+1023))/1024); +} diff --git a/util/ncgg/scan.l b/util/ncgg/scan.l new file mode 100644 index 000000000..11cff7567 --- /dev/null +++ b/util/ncgg/scan.l @@ -0,0 +1,99 @@ +%{ +#ifndef NORCSID +static char rcsid2[]= "$Header$"; +#endif + +char *mystrcpy(); +int myatoi(); + +int lineno=1; +extern char *filename; +%} + +%% +"/*" { char c; + c = input(); if (c=='\n') lineno++; + do { + while (c!='*') { + c = input(); + if (c=='\n') lineno++; + } + c = input(); + if (c=='\n') lineno++; + } while (c!='/'); + } +^\#[ \t]+[0-9]+[ \t]+\".*\"$ { + int ind,ind2; + lineno=atoi(yytext+1)-1; + for(ind=0;yytext[ind]!='"';ind++) + ; + for(ind2=ind+1;yytext[ind2]!='"';ind2++) + ; + yytext[ind2]=0; + if (strcmp(yytext+ind+1,filename)!=0) + filename=mystrcpy(yytext+ind+1); + } +[a-z]{3} { if (!emhere || (yylval.yy_int=mlookup(yytext))==0) + REJECT; + return(EMMNEM); + } + +"==" return(CMPEQ); +"!=" return(CMPNE); +"<" return(CMPLT); +"<=" return(CMPLE); +">" return(CMPGT); +">=" return(CMPGE); +"||" return(OR2); +"&&" return(AND2); +"<<" return(LSHIFT); +">>" return(RSHIFT); +"!" return(NOT); +"~" return(COMP); +":ro" { yylval.yy_int = AD_RO; return(ADORNACCESS); } +":wo" { yylval.yy_int = AD_WO; return(ADORNACCESS); } +":rw" { yylval.yy_int = AD_RW; return(ADORNACCESS); } +":cc" { yylval.yy_int = AD_CC; return(ADORNCC); } +\$[0-9]+ { yylval.yy_int = atoi(yytext+1); return(DOLLAR); } +\%[0-9]+ { yylval.yy_int = atoi(yytext+1); return(PERCENT); } +\%[a-z] { yylval.yy_int = yytext[1]-'a'; return(ALLREG); } +[0-9]+|0x[0-9A-Fa-f]+ { yylval.yy_int = myatoi(yytext); return(NUMBER); } +[_A-Za-z][_A-Za-z0-9]* { register symbol *sy_p; + if ((sy_p=lookup(yytext,symkeyw,justlooking))!=0) + return(sy_p->sy_value.syv_keywno); + yylval.yy_str = mystrcpy(yytext); return(IDENT); + } +\%[_A-Za-z][_A-Za-z0-9]* { yylval.yy_str = mystrcpy(yytext+1); + return(PERC_IDENT); + } +\"[^"\n]*\" { yytext[yyleng-1]=0; + yylval.yy_str = mystrcpy(yytext+1); + return(STRING); + } +[0-9][bf] { yytext[2]=0; + yylval.yy_str = mystrcpy(yytext); + return(STRING); + } +\n { lineno++; } +[ \t]* ; +. return(yytext[0]); +%% +int skipping=0; + +yywrap() { + + if (skipping) + fatal("EOF reached during error recovery"); + return(1); +} + +skipupto(tok,str) char *str; { + register i; + + skipping=1; + while (yylex()!=tok) + ; + for(i=strlen(str); i>0; i--) + unput(str[i-1]); + skipping=0; +} diff --git a/util/ncgg/set.c b/util/ncgg/set.c new file mode 100644 index 000000000..54e3f1f1d --- /dev/null +++ b/util/ncgg/set.c @@ -0,0 +1,118 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "param.h" +#include "property.h" +#include "set.h" +#include "token.h" +#include "lookup.h" +#include +#include "extern.h" + +extern set_t l_sets[]; + +setlookup(s) set_t s; { + register set_p p; + register i; + int setno; + + for(p=l_sets;p<&l_sets[nsets];p++) { + if (p->set_size != s.set_size) + continue; + for (i=0;iset_val[i] != s.set_val[i]) + goto cont; + return(p-l_sets); + cont:; + } + setno = NEXT(nsets,MAXSETS,"Sets"); + l_sets[setno] = s; + return(setno); +} + +make_std_sets() { + set_t s; + register i; + + for(i=0;isy_type) { + default: + error("%s is wrong kind of symbol",name); + return(emptyset); + case symprop: + pp = &l_props[sy_p->sy_value.syv_propno]; + result.set_size = pp->pr_size; + for (i=0;ipr_regset[i]; + BIS(result.set_val,0); + for (;isy_value.syv_tokno+nregs; + for (i=0;isy_value.syv_tokno]->tk_size; + break; + case symset: + return(l_sets[sy_p->sy_value.syv_setno]); + } + return(result); +} + +set_t setproduct(s1,s2) set_t s1,s2; { + set_t result; + register i; + + if ((result.set_size=s1.set_size)==0) + result.set_size = s2.set_size; + for(i=0;i +#include "extern.h" + +n_proc(name) char *name; { + register symbol *sy_p; + extern int npatbytes; + + sy_p = lookup(name,symproc,newsymbol); + sy_p->sy_value.syv_procoff = npatbytes; +} + +struct varinfo * +make_erase(name) char *name; { + expr_t e,ident_expr(); + struct varinfo *result; + + e = ident_expr(name); + if (e.ex_typ != TYPREG) + error("Register name required here"); + NEW(result,struct varinfo); + result->vi_next = VI_NULL; + result->vi_int[0] = e.ex_index; + return(result); +} + +n_instr(name,asname,oplist,eraselist,cost) +char *name,*asname; +operand *oplist; +struct varinfo *eraselist,*cost; +{ + register instrno; + register cc_count; + register instr_p ip; + + instrno = NEXT(ninstr,MAXINSTR,"Instructions"); + ip = &l_instr[instrno]; + ip->i_name = name; + ip->i_asname = strlookup(asname!=0 ? asname : name); + ip->i_nops = 0; + ip->i_oplist = oplist; + ip->i_erases = eraselist; + if (cost==0) { + ip->i_cost.ct_space = 0; + ip->i_cost.ct_time = 0; + } else { + ip->i_cost.ct_space = cost->vi_int[0]; + ip->i_cost.ct_space = cost->vi_int[1]; + } + for (cc_count=0; oplist!=0; oplist = oplist->o_next) { + ip->i_nops++; + if(oplist->o_adorn&AD_CC) + cc_count++; + } + while (eraselist!=VI_NULL) { + if (eraselist->vi_int[0] == -1 && cc_count) + error("Instruction can't both set and break the condition codes"); + eraselist=eraselist->vi_next; + } + if (cc_count>1) + error("No instruction can set condition codes more than once"); +} + +n_set(name,number) char *name; { + register symbol *sy_p; + + sy_p = lookup(name,symset,newsymbol); + sy_p->sy_value.syv_setno = number; +} + +n_tok(name,atts,size,cost,format) +char *name; +struct varinfo *atts,*cost,*format; +{ + register symbol *sy_p; + register token_p tp; + register struct varinfo *vip; + int i; + int tokno; + char formstr[50],smallstr[2]; + + sy_p = lookup(name,symtok,newsymbol); + NEW(tp,token_t); + tokno = NEXT(ntokens,MAXTOKENS,"Tokens"); + sy_p->sy_value.syv_tokno = tokno; + l_tokens[tokno] = tp; + tp->tk_name = sy_p->sy_name; + tp->tk_size = size; + if (cost != 0) { + tp->tk_cost.ct_space = cost->vi_int[0]; + tp->tk_cost.ct_time = cost->vi_int[1]; + } else { + tp->tk_cost.ct_space = 0; + tp->tk_cost.ct_time = 0; + } + for(i=0,vip=atts;ivi_next) { + tp->tk_att[i].ta_type = vip->vi_int[0]; + tp->tk_att[i].ta_name = vip->vi_str[0]; + vip->vi_str[0]=0; + } + if (i>maxtokensize) + maxtokensize=i; + if (vip!=0) + error("More then %d attributes, rest discarded",MAXATT); + for(;itk_att[i].ta_type= -3; + if (format!=0) { + formstr[0] = 0; + for (vip=format;vip!=0;vip=vip->vi_next) { + if (vip->vi_int[0]==0) + strcat(formstr,vip->vi_str[0]); + else { + for(i=0;ivi_str[0],tp->tk_att[i].ta_name)==0) { + smallstr[0] = i+1; + smallstr[1] = 0; + strcat(formstr,smallstr); + break; + } + } + if (i==MAXATT) + error("%s not a known attribute", + vip->vi_str[0]); + } + } + tp->tk_format = strlookup(formstr); + } else + tp->tk_format = -1; +} + +checkprintformat(n) { + register short *s; + register i; + extern set_t l_sets[]; + + s= l_sets[n].set_val; + for(i=nregs;itk_format<0) + error("Token %s in set does not have printformat", + l_tokens[i-nregs]->tk_name); +} + +n_prop(name,size) char *name; int size; { + int propno; + register symbol *sp; + + propno = NEXT(nprops,MAXPROPS,"Properties"); + sp = lookup(name,symprop,newsymbol); + sp->sy_value.syv_propno = propno; + if (size <= 0) { + error("Size of property must be >0"); + size = wordsize; + } + l_props[propno].pr_size = size; +} + +prophall(n) { + register i; + short hallset[SETSIZE]; + + for(i=0;isy_value.syv_regno = regno = NEXT(nregs,MAXREGS,"Number of registers"); + ri_p = &l_regs[regno]; + ri_p->ri_name = mystrcpy(name); + ri_p->ri_repr = printstring!=0 ? mystrcpy(printstring) : ri_p->ri_name; + ri_p->ri_memb[0] = member1; + ri_p->ri_memb[1] = member2; + if (nmemb>maxmembers) + maxmembers=nmemb; + return(regno); +} + +make_const() { + + wordsize = cmustbeset("EM_WSIZE"); + pointersize = cmustbeset("EM_PSIZE"); +} + +cmustbeset(ident) char *ident; { + + return(lookup(ident,symconst,mustexist)->sy_value.syv_cstval); +} + +n_const(ident,val) char *ident; { + register symbol *sy_p; + + sy_p = lookup(ident,symconst,newsymbol); + sy_p->sy_value.syv_cstval = val; +} + +n_sconst(ident,val) char *ident,*val; { + register symbol *sy_p; + + sy_p = lookup(ident,symsconst,newsymbol); + sy_p->sy_value.syv_stringno = strlookup(val); +} + +regline(rl,pl,rv) varinfo *rl,*pl; { + register varinfo *rrl,*rpl; + register short *sp; + register reginfo *regp; + int thissize; + int propno; + + for(rrl=rl;rrl!=0;rrl=rrl->vi_next) { + regp = &l_regs[rrl->vi_int[0]]; + thissize = 0; + for(rpl=pl;rpl!=0;rpl=rpl->vi_next) { + propno = rpl->vi_int[0]; + sp= l_props[propno].pr_regset; + BIS(sp,rrl->vi_int[0]); + if (thissize==0) + thissize = l_props[propno].pr_size; + else if (thissize!=-1 && thissize!=l_props[propno].pr_size) + error("Register %s has no clear size", + regp->ri_name); + } + regp->ri_size = thissize; + regp->ri_class = regclass; + regp->ri_rregvar = rv; + if (rv>=0) { + if (regp->ri_memb[0]!=0) + error("Register variables may not have subregisters"); + rvused |= ANY_REGVAR; + if (regp->ri_size == wordsize) + rvused |= SL_REGVAR; + else if (regp->ri_size == 2*wordsize) + rvused |= DL_REGVAR; + if (nregvar[rv]==0) + rvsize[rv] = regp->ri_size; + else if (rvsize[rv]!=regp->ri_size) + error("All register variables of one type must have the same size"); + NEXT(nregvar[rv],MAXREGVAR,"Register variable"); + rvnumbers[rv][nregvar[rv]-1] = rrl->vi_int[0]; + } + } + regclass++; +} + +setallreg(vi) struct varinfo *vi; { + + nallreg=0; + for(;vi!=0;vi=vi->vi_next) { + if (vi->vi_int[0]<0) + continue; + allreg[nallreg++] = vi->vi_int[0]; + } +} + +freevi(vip) register struct varinfo *vip; { + register i; + extern char *end; + + if (vip==0) + return; + freevi(vip->vi_next); + freevi(vip->vi_vi); + for (i=0;ivi_str[i]>end) + free((char *) vip->vi_str[i]); + free(vip); +} + +int myatoi(s) register char *s; { + register int base=10; + register sum=0; + + if (*s=='0') { + base = 8; + s++; + if (*s=='x') { + base=16; + s++; + } + } + for (;;) { + switch (*s) { + default: return(sum); + case '8': + case '9': + if (base==8) error("Bad digit in octal number"); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + sum = sum*base + *s++ - '0'; + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + if (base!=16) error("Hexletter in number not expected"); + sum = sum*base + *s++ - 'a'; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + if (base!=16) error("Hexletter in number not expected"); + sum = sum*base + *s++ - 'A'; + break; + } + } +} + +char *mystrcpy(s) char *s; { + register char *p; + char *myalloc(); + + p=myalloc(strlen(s)+1); + strcpy(p,s); + return(p); +} + +char *myalloc(n) register n; { + register char *p,*result; + char *malloc(); + + result=p=malloc(n); + if (p== (char *) 0) + fatal("Out of memory"); + do *p++=0; while (--n); + return(result); +} + +chkincl(value,lwb,upb) { + + if (valueupb) + error("Number %d should have been between %d and %d", + value,lwb,upb); + return(value); +} + +subset(sp1,sp2,setsize) short *sp1,*sp2; { + register i; + + for(i=0;ivi_next; + l++; + } + return(l); +} diff --git a/util/ncgg/var.c b/util/ncgg/var.c new file mode 100644 index 000000000..97ba265d1 --- /dev/null +++ b/util/ncgg/var.c @@ -0,0 +1,45 @@ +#ifndef NORCSID +static char rcsid[]= "$Header$"; +#endif + +#include "param.h" +#include "reg.h" +#include "property.h" +#include "token.h" +#include "set.h" +#include "instruct.h" +#include "lookup.h" +#include + +int wordsize; +int pointersize; +int nregs=1; +int nprops; +int ntokens=1; +int nsets; +int ninstr; +int codeindex; +int empatlen,emmnem[EMPATMAX]; +int empatexpr; +int tokpatlen,tokpatset[TOKPATMAX],tokpatro[TOKPATMAX]; +int nallreg,allreg[MAXALLREG]; +int cursetno; +int allsetno; +int inproc=0; /* scanning "procedure" */ +int callproc=0; +int procarg[2]; +int fc1=1,fc2=1,fc3=1,fc4=1; +int maxmembers=0; +int regclass=1; +int maxtokensize=0; +int rvused=0; +int nregvar[4]; +int rvsize[4]; +int rvnumbers[4][MAXREGVAR]; + +reginfo l_regs[MAXREGS]; +propinfo l_props[MAXPROPS]; +token_p l_tokens[MAXTOKENS]; +set_t l_sets[MAXSETS]; +instr_t l_instr[MAXINSTR]; +symbol *symhash[NSYMHASH];