*** empty log message ***
authorsater <none@none>
Tue, 8 Jan 1985 09:59:28 +0000 (09:59 +0000)
committersater <none@none>
Tue, 8 Jan 1985 09:59:28 +0000 (09:59 +0000)
20 files changed:
util/ncgg/Makefile [new file with mode: 0644]
util/ncgg/cgg.y [new file with mode: 0644]
util/ncgg/coerc.c [new file with mode: 0644]
util/ncgg/cvtkeywords [new file with mode: 0755]
util/ncgg/emlookup.c [new file with mode: 0644]
util/ncgg/error.c [new file with mode: 0644]
util/ncgg/expr.c [new file with mode: 0644]
util/ncgg/hall.c [new file with mode: 0644]
util/ncgg/instruct.c [new file with mode: 0644]
util/ncgg/iocc.c [new file with mode: 0644]
util/ncgg/keywords [new file with mode: 0644]
util/ncgg/lookup.c [new file with mode: 0644]
util/ncgg/main.c [new file with mode: 0644]
util/ncgg/makedepend [new file with mode: 0755]
util/ncgg/output.c [new file with mode: 0644]
util/ncgg/scan.l [new file with mode: 0644]
util/ncgg/set.c [new file with mode: 0644]
util/ncgg/strlookup.c [new file with mode: 0644]
util/ncgg/subr.c [new file with mode: 0644]
util/ncgg/var.c [new file with mode: 0644]

diff --git a/util/ncgg/Makefile b/util/ncgg/Makefile
new file mode 100644 (file)
index 0000000..2933946
--- /dev/null
@@ -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 (file)
index 0000000..37ece48
--- /dev/null
@@ -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 <cgg_cg.h>
+#include <em_reg.h>
+
+extern int lineno;
+int instline,saveline;
+int startline;
+int npatterns;
+int patindex[MAXPATTERNS];
+
+int emhere=0;  /* lexical analyzer flag */
+int optexact=0;        /* Inside "with exact" rule */
+int optstack=0;        /* Inside with <blah> STACK rule */
+int saferulefound=0;
+int maxempatlen=0;
+int maxrule=0;
+struct varinfo *defcost;
+
+struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
+struct varinfo *make_erase();
+expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr();
+expr_t perc_ident_expr(),sum_expr(),regvar_expr();
+
+set_t ident_to_set(),setproduct(),setsum(),setdiff();
+
+iocc_t subr_iocc(),tokm_iocc(),ident_iocc(),all_iocc(),descr_iocc();
+
+extern int narexpr;
+extern expr_t arexp[];
+
+int niops;
+iocc_t iops[20];
+%}
+
+%union {
+       int yy_int;
+       char * yy_str;
+       varinfo * yy_varinfo;
+       set_t yy_set;
+       operand *yy_oplist;
+       expr_t yy_expr;
+       iocc_t yy_iocc;
+}
+
+%token PROPERTIES
+%token REGISTERS
+%token TOKENS
+%token SETS
+%token MOVES
+%token TESTS
+%token STACKINGRULES COERCIONS
+%token INSTRUCTIONS
+%token PROC CALL EXAMPLE
+%token FROM TO
+%token TEST MOVE STACK RETURN
+%token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING
+%token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW
+%token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP
+%token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER
+%token <yy_int> ADORNACCESS
+%token <yy_int> ADORNCC
+%token INT
+%token ADDR
+%token <yy_int> EMMNEM
+%token <yy_int> NUMBER
+%token <yy_int> DOLLAR PERCENT ALLREG
+%token <yy_str> IDENT PERC_IDENT
+%token <yy_str> STRING
+%token TIMEFACTOR SIZEFACTOR
+%token COST
+%type <yy_varinfo> prop_list property ident_list ident_list_el
+%type <yy_varinfo> att_list att_list_el structdecl optcost optformat
+%type <yy_varinfo> kills allocates yields leaving
+%type <yy_varinfo> generates kill_list kill_list_el uselist uselist_el genlist yieldlist
+%type <yy_varinfo> leavelist leavelist_el gen_instruction
+%type <yy_varinfo> opt_erase_list erase_list erase_list_el
+%type <yy_str> opt_par_string optstring
+%type <yy_int> register propno att_list_el_type tokenset_no
+%type <yy_int> adornlist optstar optuses optregvar regvartype optregvartype
+%type <yy_int> emarg tokarg subreg allreg optsecondstring
+%type <yy_expr> expr
+%type <yy_iocc> tokeninstance
+%type <yy_int> optexpr optexact optstack
+%type <yy_set> tokenset
+%type <yy_oplist> oplist oplist_el
+
+%left OR2
+%left AND2
+%left CMPEQ,CMPNE
+%left CMPLT,CMPLE,CMPGT,CMPGE
+%left RSHIFT,LSHIFT
+%left '+','-'
+%left '*','/','%'
+%nonassoc NOT,COMP,UMINUS
+
+%start machtable
+
+%%
+/*
+ * The machine table consists of a number of sections, with their
+ * own associated parsers.
+ */
+machtable
+       : constants
+         properties
+         registers
+         tokens
+               { make_std_sets(); }
+         sets
+         instructions
+         moves
+         tests
+         stacks
+         coercs
+         code
+       ;
+
+/*
+ * Constants are parsed as name=value pairs
+ */
+constants
+       : constdeflist
+       ;
+constdeflist
+       : /* empty */
+       | constdeflist constdef
+       ;
+constdef
+       : IDENT'=' NUMBER
+               { n_const($1,$3); free($1); }
+       | IDENT '=' STRING
+               { n_sconst($1,$3); free($1); free($3); }
+       | TIMEFACTOR '=' NUMBER '/' NUMBER
+               { fc1 = $3; fc2 = $5; }
+       | SIZEFACTOR '=' NUMBER '/' NUMBER
+               { fc3 = $3; fc4 = $5; }
+       | error
+       ;
+
+/*
+ * Properties are parsed as a list of names optionally followed by their size
+ */
+properties
+       : PROPERTIES  { make_const(); } prdef_list
+       ;
+prdef_list
+       : prdef_list_el
+       | prdef_list optcomma prdef_list_el
+       ;
+prdef_list_el
+       : IDENT
+               { n_prop($1,wordsize); free($1); }
+       | IDENT '(' NUMBER ')'
+               { n_prop($1,$3); free($1); }
+       ;
+
+/*
+ * Registers are rows of reglist:proplist pairs
+ */
+registers
+       : REGISTERS regdef_list
+       ;
+regdef_list
+       : regdef_list_el
+       | regdef_list regdef_list_el
+       ;
+regdef_list_el
+       : ident_list ':' prop_list optregvar '.'
+               { regline($1,$3,$4); free((char *) $1); free((char *) $3); }
+       | error '.'
+       ;
+optregvar
+       : /* empty */
+               { $$ = -1; }
+       | REGVAR
+               { $$ = reg_any; }
+       | REGVAR '(' regvartype ')'
+               { $$ = $3; }
+       ;
+
+regvartype
+       : REG_ANY
+               { $$ = reg_any;}
+       | REG_FLOAT
+               { $$ = reg_float;}
+       | REG_LOOP
+               { $$ = reg_loop;}
+       | REG_POINTER
+               { $$ = reg_pointer;}
+       ;
+
+ident_list
+       : ident_list_el
+       | ident_list optcomma ident_list_el
+               { $3->vi_next = $1; $$ = $3; }
+       ;
+ident_list_el
+       : IDENT opt_par_string
+               { NEW($$,struct varinfo);
+                 $$->vi_next = 0;
+                 $$->vi_int[0] = n_reg($1,$2,0,0,0);
+                 free($1); if($2!=0) free($2);
+               }
+       | IDENT opt_par_string '=' register
+               { NEW($$,struct varinfo);
+                 $$->vi_next = 0;
+                 $$->vi_int[0] = n_reg($1,$2,1,$4,0);
+                 free($1); if($2!=0) free($2);
+               }
+       | IDENT opt_par_string '=' register '+' register
+               { NEW($$,struct varinfo);
+                 $$->vi_next = 0;
+                 $$->vi_int[0] = n_reg($1,$2,2,$4,$6);
+                 free($1); if($2!=0) free($2);
+               }
+       ;
+opt_par_string
+       : /* empty */
+               { $$ = 0; }
+       | '(' STRING ')'
+               { $$ = $2; }
+       ;
+register
+       : IDENT
+               { register symbol *sy_p;
+
+                 sy_p = lookup($1,symreg,mustexist);
+                 $$ = sy_p->sy_value.syv_regno;
+                 free($1);
+               }
+       ;
+prop_list
+       : property
+       | prop_list optcomma property
+               { $3->vi_next = $1; $$ = $3; }
+       ;
+property
+       : IDENT
+               { register symbol *sy_p;
+                 sy_p = lookup($1,symprop,mustexist);
+                 NEW($$,struct varinfo);
+                 $$->vi_next=0;
+                 $$->vi_int[0]=sy_p->sy_value.syv_propno;
+                 free($1);
+               }
+       ;
+propno
+       : IDENT
+               { register symbol *sy_p;
+                 sy_p = lookup($1,symprop,mustexist);
+                 $$ = sy_p->sy_value.syv_propno;
+                 free($1);
+               }
+       ;
+
+/* tokens are parsed as struct definitions
+ * types in the struct can be register properties, ADDR or INT
+ */
+
+tokens
+       : TOKENS tokdeflist
+       ;
+tokdeflist
+       : tokdeflist_el
+       | tokdeflist tokdeflist_el
+       ;
+tokdeflist_el
+       : IDENT '=' structdecl NUMBER optcost optformat '.'
+               { n_tok($1,$3,$4,$5,$6);
+                 free($1);
+                 freevi($3);
+                 freevi($5);
+                 freevi($6);
+               }
+       | error '.'
+       ;
+structdecl
+       : '{' att_list '}'
+               { $$ = $2; }
+       ;
+att_list
+       : /* empty */
+               { $$ = 0; }
+       | att_list_el att_list
+               { $1->vi_next = $2; $$ = $1; }
+       ;
+att_list_el
+       : att_list_el_type IDENT ';'
+               { NEW ($$,struct varinfo);
+                 $$->vi_next = 0;
+                 $$->vi_int[0] = $1;
+                 $$->vi_str[0] = $2;
+               }
+       ;
+att_list_el_type
+       : INT
+               { $$ = -1; }
+       | ADDR
+               { $$ = -2; }
+       | propno
+       ;
+optcost
+       :
+               { if (defcost==VI_NULL)
+                       $$=VI_NULL;
+                 else {
+                       NEW($$,struct varinfo);
+                       *$$ = *defcost;
+                 }
+               }
+       | COST '(' NUMBER ',' NUMBER ')'
+               { NEW ($$,struct varinfo);
+                 $$->vi_int[0] = $3;
+                 $$->vi_int[1] = $5;
+               }
+       ;
+optformat
+       :
+               { $$ = 0; }
+       | STRING optformat
+               { NEW($$,struct varinfo);
+                 $$->vi_next = $2;
+                 $$->vi_int[0] = 0;
+                 $$->vi_str[0] = $1;
+               }
+       | IDENT optformat
+               { NEW($$,struct varinfo);
+                 $$->vi_next = $2;
+                 $$->vi_int[0] = 1;
+                 $$->vi_str[0] = $1;
+               }
+       ;
+optcomma
+       : ','
+       | /* empty */
+       ;
+
+/* sets are parsed as ident = expression */
+
+sets
+       : SETS setdeflist
+       ;
+setdeflist
+       : setdeflist_el
+       | setdeflist setdeflist_el
+       ;
+setdeflist_el
+       : IDENT '=' tokenset_no '.'
+               { n_set($1,$3); free($1); }
+       | error '.'
+       ;
+tokenset_no
+       : tokenset
+               { $$ = setlookup($1); }
+       ;
+tokenset
+       : IDENT
+               { $$ = ident_to_set($1); free($1); }
+       | tokenset '*' tokenset
+               { $$ = setproduct($1,$3); }
+       | tokenset '+' tokenset
+               { $$ = setsum($1,$3); }
+       | tokenset '-' tokenset
+               { $$ = setdiff($1,$3); }
+       | '(' tokenset ')'
+               { $$ = $2; }
+       ;
+
+instructions
+       : INSTRUCTIONS optcost instdef_list
+               { defcost = $2; }
+       ;
+instdef_list
+       : instdef_list_el
+       | instdef_list instdef_list_el
+       ;
+instdef_list_el
+       : IDENT optstring oplist opt_erase_list optcost '.'
+               { n_instr($1,$2,$3,$4,$5); freevi($5); }
+       | error '.'
+       ;
+oplist
+       : /* empty */
+               { $$ = 0; }
+       | oplist_el
+       | oplist_el ',' oplist
+               { $$ = $1; $$->o_next = $3; }
+       ;
+oplist_el
+       : tokenset_no adornlist
+               { NEW($$,struct operand);
+                 $$->o_next  = 0 ;
+                 $$->o_setno = $1;
+                 $$->o_adorn = $2;
+                 checkprintformat($1);
+               }
+       ;
+adornlist
+       : /* empty */
+               { $$ = 0; }
+       | ADORNACCESS adornlist
+               { if ($2&AD_RWMASK)
+                       error("Only one of :ro,:wo,:rw allowed");
+                 $$ = $1 | $2;
+               }
+       | ADORNCC adornlist
+               { $$ = $1|$2; }
+       ;
+opt_erase_list
+       : /* empty */
+               { $$ = VI_NULL;}
+       | KILLS erase_list
+               { $$ = $2; }
+       ;
+erase_list
+       : erase_list_el
+               { $$ = $1; }
+       | erase_list_el erase_list
+               { $1->vi_next = $2; $$ = $1; }
+       ;
+erase_list_el
+       : IDENT
+               { $$ = make_erase($1); }
+       | ADORNCC
+               { NEW($$, struct varinfo);
+                 $$->vi_int[0] = -1;
+                 $$->vi_next = VI_NULL;
+               }
+       ;
+
+/* Now the moves */
+
+moves
+       : MOVES movedeflist
+       | /* empty */
+       ;
+movedeflist
+       : movedeflist_el
+       | movedeflist movedeflist_el
+       ;
+movedeflist_el
+       : FROM
+               {startline = lineno; }
+         tokenset_no
+               { cursetno = $3; }
+         optexpr TO tokenset_no
+               { cursetno = $7;
+                 tokpatlen=2;
+                 tokpatset[0] = $3;
+                 tokpatset[1] = $7;
+                 tokpatro[0] = 1;
+               }
+       optexpr GEN genlist
+               { tokpatlen=0;
+                 tokpatro[0]=0;
+                 n_move($3,$5,$7,$9,$11);
+                 freevi($11);
+               }
+       | error
+       ;
+
+/* Now the test part */
+
+tests
+       : TESTS testdeflist
+       | /* empty */
+       ;
+testdeflist
+       : testdeflist_el
+       | testdeflist testdeflist_el
+       ;
+testdeflist_el
+       : TO
+               { startline = lineno;}
+         TEST tokenset_no
+               { cursetno = $4;
+                 tokpatlen=1;
+                 tokpatset[0]=$4;
+                 tokpatro[0] = 1;
+               }
+         optexpr GEN genlist
+               { tokpatlen=0;
+                 tokpatro[0] = 0;
+                 n_test($4,$6,$8);
+                 freevi($8);
+               }
+       | error
+       ;
+         
+/* Now the stacks */
+
+stacks
+       : STACKINGRULES stackdeflist
+       ;
+stackdeflist
+       : stackdeflist_el
+       | stackdeflist stackdeflist_el
+       ;
+stackdeflist_el
+       : FROM
+               {startline = lineno;}
+         tokenset_no
+               { cursetno = $3; 
+                 tokpatlen=1; 
+                 tokpatset[0] = $3; 
+                 tokpatro[0] = 1;
+               }
+         optexpr TO STACK optuses GEN genlist
+               { tokpatro[0] = 0;
+                 n_stack($3,$5,$8,$10);
+                 freevi($10);
+               }
+       ;
+optuses
+       : /* empty */
+               { $$ = 0; nallreg=0;}
+       | USES propno
+               { $$ = $2; nallreg = 1; allreg[0] = $2; }
+       ;
+
+/* Now the one-to-one coercion rules */
+
+coercs
+       : COERCIONS coercdeflist
+       ;
+coercdeflist
+       : coercdeflist_el
+       | coercdeflist coercdeflist_el
+       ;
+coercdeflist_el
+       : FROM
+               {startline = lineno; tokpatlen=0; inithall();}
+         STACK allocates GEN genlist YIELDS tokeninstance
+               { checkhall();
+                 n_coerc(0,0,$4,$6,(struct varinfo *) 0,$8);
+                 freevi($4);
+                 freevi($6);
+               }
+       | FROM
+               {startline = lineno;}
+         tokenset_no
+               { cursetno = $3; 
+                 tokpatlen=1; 
+                 tokpatset[0]=$3; 
+                 tokpatro[0] = 1;
+                 inithall();
+               }
+         optexpr allocates generates yields
+               { tokpatro[0] = 0;
+                 checkhall();
+                 n_coerc($3,$5,$6,$7,$8);
+                 freevi($6);
+                 freevi($7);
+               }
+       ;
+
+/* Now the code part */
+
+code
+       : PATTERNS coderules
+       ;
+coderules
+       : coderule
+       | coderules coderule
+       ;
+coderule
+       : PAT {emhere=1;} empattern {emhere=0;} optexpr
+               { empatexpr = $5;
+                 npatterns = 0;
+                 saferulefound=0;
+                 if (empatlen>maxempatlen)
+                       maxempatlen=empatlen;
+               }
+         patterns
+               { if (!saferulefound)
+                       error("Previous rule impossible on empty stack");
+                 outpatterns();
+               }
+       | PROC IDENT example
+               { npatterns = 0; saferulefound=0; inproc=1; n_proc($2); }
+         patterns
+               { if (!saferulefound)
+                       error("Previous rule impossible on empty stack");
+                 outpatterns(); inproc=0;
+               }
+       | error
+               { skipupto(PAT,"pat"); yyerrok; yyclearin; }
+       ;
+example
+       : /* empty */
+               { empatlen = 0; }
+       | EXAMPLE {emhere=1;} empattern {emhere=0;}
+       ;
+empattern
+       : EMMNEM
+               { empatlen = 1; emmnem[0] = $1; }
+       | empattern EMMNEM
+               { NEXT(empatlen,EMPATMAX,"Em pattern");
+                 emmnem[empatlen-1] = $2;
+               }
+       ;
+patterns
+       : onepattern
+               { saferulefound=1;
+                 callproc=0;
+               }
+       | morepatterns
+               { callproc=0;
+                 if (npatterns>maxrule)
+                       maxrule=npatterns;
+               }
+       | CALL IDENT '(' STRING optsecondstring ')'
+               { register symbol *sy_p;
+                 saferulefound=1;
+                 sy_p=lookup($2,symproc,mustexist);
+                 callproc=sy_p->sy_value.syv_procoff;
+                 procarg[0] = strlookup($4);
+                 procarg[1] = $5;
+                 free($2);
+                 free($4);
+               }
+       ;
+optsecondstring
+       : /* empty */
+               { $$ = 0; }
+       | ',' STRING
+               { $$ = strlookup($2); free($2); }
+       ;
+
+onepattern
+       :       { inithall(); startline=lineno; tokpatlen=0; }
+         kills allocates generates yields leaving
+               { optexact=0; optstack=0;
+                 patindex[npatterns++]=codeindex;
+                 checkhall();
+                 dopattern(0,$2,$3,$4,$5,$6);
+                 freevi($2);
+                 freevi($3);
+                 freevi($4);
+                 freevi($5);
+                 freevi($6);
+               }
+       ;
+morepatterns
+       : { inithall(); } pattern
+       | morepatterns { inithall(); } pattern
+       ;
+
+pattern
+       : stackpattern kills allocates generates yields leaving
+               { patindex[NEXT(npatterns,MAXPATTERNS,"Patterns")]=codeindex;
+                 if (hall() && !optexact) saferulefound=1;
+                 dopattern(0,$2,$3,$4,$5,$6);
+                 freevi($2);
+                 freevi($3);
+                 freevi($4);
+                 freevi($5);
+                 freevi($6);
+               }
+       ;
+stackpattern
+       : WITH optexact
+               { startline = lineno; }
+         setlist optstack
+       ;
+optexact
+       : /* empty */
+               { $$ = optexact = 0; }
+       | EXACT
+               { $$ = optexact = 1; }
+       ;
+optstack
+       : /* empty */
+               { $$ = optstack = 0; }
+       | STACK
+               { $$ = optstack = 1; }
+       ;
+
+setlist
+       : /* empty */
+               { tokpatlen = 0; }
+       | setlist tokenset_no
+               { NEXT(tokpatlen,TOKPATMAX,"Stack pattern");
+                 tokpatset[tokpatlen-1] = $2;
+                 checkunstacking($2);
+               }
+       ;
+kills
+       : /* empty */
+               { $$ = 0; }
+       | KILLS kill_list
+               { $$ = $2;
+                 if (optstack)
+                       error("No sense in giving kills in this pattern");
+               }
+       ;
+kill_list
+       : kill_list_el
+       | kill_list_el ',' kill_list
+               { $$=$1; $$->vi_next = $3; }
+       ;
+kill_list_el
+       : tokenset_no { cursetno=$1; } optexpr
+               { NEW($$,struct varinfo);
+                 $$->vi_next = 0;
+                 $$->vi_int[0]=$1;
+                 $$->vi_int[1]=$3;
+               }
+       ;
+allocates
+       : /* empty */
+               { $$ = 0; nallreg=0;}
+       | USES uselist
+               { $$ = $2; setallreg($2); }
+       ;
+uselist
+       : uselist_el
+               { prophall($1->vi_int[0]); }
+       | uselist_el ',' uselist
+               { prophall($1->vi_int[0]); $$=$1; $$->vi_next=$3; }
+       ;
+uselist_el
+       : property
+               { $$=$1; $$->vi_int[1] = 0; }
+       | property '=' tokeninstance
+               { if (!existalmove($3,$$->vi_int[0]))
+                       error("No such move defined");
+                 $$=$1; $$->vi_int[1] = $3.in_index; 
+               }
+       | REUSING tokeninstance
+               { NEW($$,struct varinfo);
+                 $$->vi_next = 0;
+                 $$->vi_int[0] = -1;
+                 $$->vi_int[1] = $2.in_index;
+               }
+       ;
+
+
+generates
+       : /* empty */
+               { $$ = 0; }
+       | GEN genlist
+               { $$ = $2; }
+       ;
+genlist
+       : /* empty */
+               { $$ = 0; }
+       | gen_instruction genlist
+               { if ($1!=0) {
+                       register struct varinfo *tvip;
+                       $$=tvip=$1;
+                       while (tvip->vi_next!=VI_NULL)
+                               tvip=tvip->vi_next;
+                       tvip->vi_next = $2;
+                 } else {
+                       $$ = $2;
+                 }
+               }
+       ;
+gen_instruction
+       : {instline = lineno; } IDENT optstar gen_oplist
+               { saveline =lineno; lineno=instline;
+                 $$ = gen_inst($2,$3); free($2);
+                 lineno = saveline;
+               }
+       | NUMBER ':'
+               { $$ = gen_tlab($1); }
+       | MOVE tokeninstance ',' tokeninstance
+               { $$ = gen_move($2,$4); }
+       | TEST tokeninstance
+               { $$ = gen_test($2);}
+       | RETURN
+               { $$ = gen_preturn(); }
+       ;
+optstar
+       : /* empty */
+               { $$=0; }
+       | '*'
+               { $$=1; }
+       | '[' NUMBER ']'
+               { $$=$2; }
+       ;
+gen_oplist
+       : '.' /* empty gives conflicts */
+               { niops=0; }
+       | tokeninstance
+               { niops=1;iops[0]=$1; }
+       | gen_oplist ',' tokeninstance
+               { iops[niops++] = $3; }
+       ;
+
+yields
+       : /* empty */
+               { $$ = 0; }
+       | YIELDS yieldlist
+               { $$ = $2; }
+       ;
+yieldlist
+       : /* empty */
+               { $$ = 0; }
+       | tokeninstance yieldlist
+               { checkstacking($1.in_set);
+                 NEW($$,struct varinfo);
+                 $$->vi_next = $2;
+                 $$->vi_int[0] = $1.in_index;
+               }
+       ;
+
+leaving
+       : /* empty */
+               { $$ = 0; }
+       | LEAVING {emhere=1; } leavelist
+               { emhere=0; $$ = $3; }
+       ;
+leavelist
+       : leavelist_el
+       | leavelist_el leavelist
+               { $$=$1; $$->vi_next=$2; }
+       ;
+leavelist_el
+       : EMMNEM optexpr
+               { NEW($$,struct varinfo);
+                 $$->vi_next=0;
+                 $$->vi_int[0] = $1;
+                 $$->vi_int[1] = $2;
+               }
+       ;
+
+optstring
+       : /* empty */
+               { $$ = 0; }
+       | STRING
+       ;
+optexpr
+       : /* empty */
+               { $$ = 0; }
+       | expr
+               { $$ = $1.ex_index; }   /* type checking ? */
+       ;
+
+tokeninstance
+       : tokarg subreg
+               { $$ = subr_iocc($1,$2); }
+       | tokarg '.' IDENT
+               { $$ = tokm_iocc($1,$3); free($3); }
+       | IDENT
+               { $$ = ident_iocc($1); free($1);}
+       | allreg subreg
+               { $$ = all_iocc($1,$2); }
+       | '{' IDENT attlist '}'
+               { $$ = descr_iocc($2); free($2); }
+       ;
+attlist
+       : /* empty */
+               { narexpr = 0; }
+       | attlist ',' expr
+               { arexp[narexpr++] = $3; }
+       ;
+
+emarg
+       : DOLLAR
+               { if ($1<1 || $1>empatlen)
+                       error("Only %d instructions in pattern",empatlen);
+                 $$ = $1;
+               }
+       ;
+tokarg
+       : PERCENT
+               { if ($1<1 || $1>tokpatlen) {
+                       error("Only %d tokens in stackpattern",tokpatlen);
+                       $$ =1;
+                 } else {
+                         $$ = $1;
+                 }
+               }
+       ;
+subreg
+       : /* empty */
+               { $$ = 0; }
+       | '.' NUMBER
+               { if ($2<1 || $2>2) {
+                       error("Only 2 subregisters allowed");
+                       $$ = 1;
+                 } else {
+                       $$ = $2;
+                 }
+               }
+       ;
+allreg
+       : ALLREG
+               { if ($1>=nallreg)
+                       fatal("Only %d registers allocated",nallreg);
+                 $$ = $1;
+               }
+       ;
+
+expr
+       : NUMBER
+               { $$ = make_expr(TYPINT,EX_CON, (int) ($1 & 0xFFFF), (int) ($1>>16));
+               }
+       | emarg
+               { $$ = make_expr(argtyp(emmnem[$1-1]),EX_ARG,$1,0); }
+       | STRING
+               { $$ = make_expr(TYPADDR,EX_STRING,strlookup($1),0); free($1); }
+       | IDENT
+               { $$ = ident_expr($1); free($1); }
+       | tokarg subreg
+               { $$ = subreg_expr($1,$2); }
+       | tokarg '.' IDENT
+               { $$ = tokm_expr($1,$3); free($3); }
+       | allreg subreg
+               { $$ = all_expr($1,$2); }
+       | PERC_IDENT
+               { $$ = perc_ident_expr($1); free($1); }
+       | DEFINED '(' expr ')'
+               { $$ = make_expr(TYPBOOL,EX_DEFINED,i_expr($3),0); }
+       | SAMESIGN '(' expr ',' expr ')'
+               { $$ = make_expr(TYPBOOL,EX_SAMESIGN,i_expr($3),i_expr($5)); }
+       | SFIT '(' expr ',' expr ')'
+               { $$ = make_expr(TYPBOOL,EX_SFIT,i_expr($3),i_expr($5)); }
+       | UFIT '(' expr ',' expr ')'
+               { $$ = make_expr(TYPBOOL,EX_UFIT,i_expr($3),i_expr($5)); }
+       | ROM '(' emarg ',' NUMBER ')'
+               { $$ = make_expr(TYPINT,EX_ROM,$3-1,chkincl($5,1,3)-1); }
+       | LOWW '(' emarg ')'
+               { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
+       | HIGHW '(' emarg ')'
+               { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
+       | '(' expr ')'
+               { $$ = $2; }
+       | expr CMPEQ expr
+               { $$ = make_expr(TYPBOOL,eq2expr($1,$3),$1.ex_index,$3.ex_index); }
+       | expr CMPNE expr
+               { $$ = make_expr(TYPBOOL,ne2expr($1,$3),$1.ex_index,$3.ex_index); }
+       | expr CMPLT expr
+               { $$ = make_expr(TYPBOOL,EX_NCPLT,i_expr($1),i_expr($3)); }
+       | expr CMPGT expr
+               { $$ = make_expr(TYPBOOL,EX_NCPGT,i_expr($1),i_expr($3)); }
+       | expr CMPLE expr
+               { $$ = make_expr(TYPBOOL,EX_NCPLE,i_expr($1),i_expr($3)); }
+       | expr CMPGE expr
+               { $$ = make_expr(TYPBOOL,EX_NCPGE,i_expr($1),i_expr($3)); }
+       | expr OR2 expr
+               { $$ = make_expr(TYPBOOL,EX_OR2,b_expr($1),b_expr($3)); }
+       | expr AND2 expr
+               { $$ = make_expr(TYPBOOL,EX_AND2,b_expr($1),b_expr($3)); }
+       | expr '+' expr
+               { $$ = sum_expr($1,$3); }
+       | expr '-' expr
+               { $$ = make_expr(TYPINT,EX_MINUS,i_expr($1),i_expr($3)); }
+       | expr '*' expr
+               { $$ = make_expr(TYPINT,EX_TIMES,i_expr($1),i_expr($3)); }
+       | expr '/' expr
+               { $$ = make_expr(TYPINT,EX_DIVIDE,i_expr($1),i_expr($3)); }
+       | expr '%' expr
+               { $$ = make_expr(TYPINT,EX_MOD,i_expr($1),i_expr($3)); }
+       | expr LSHIFT expr
+               { $$ = make_expr(TYPINT,EX_LSHIFT,i_expr($1),i_expr($3)); }
+       | expr RSHIFT expr
+               { $$ = make_expr(TYPINT,EX_RSHIFT,i_expr($1),i_expr($3)); }
+       | NOT expr
+               { $$ = make_expr(TYPBOOL,EX_NOT,b_expr($2),0); }
+       | COMP expr
+               { $$ = make_expr(TYPINT,EX_COMP,i_expr($2),0); }
+       | INREG '(' expr ')'
+               { $$ = make_expr(TYPINT,EX_INREG,i_expr($3),0); }
+       | regvartype
+               { $$ = make_expr(TYPINT,EX_CON, $1+1, 0); }
+       | REGVAR '(' expr optregvartype ')'
+               { $$ = regvar_expr($3,$4); }
+       ;
+
+optregvartype
+       : /* empty */
+               { $$ = reg_any; }
+       | ',' regvartype
+               { $$ = $2; }
+       ;
+%%
+#include "scan.c"
diff --git a/util/ncgg/coerc.c b/util/ncgg/coerc.c
new file mode 100644 (file)
index 0000000..b2ab826
--- /dev/null
@@ -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 <cgg_cg.h>
+#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;i<MAXREGS+MAXTOKENS;i++)
+           if (BIT(l_sets[mp->m_set1].set_val,i))
+               for(j=0;j<SETSIZE;j++)
+                   posmoves[i][j] |= l_sets[mp->m_set2].set_val[j];
+}
+
+existmove(from,sp) iocc_t from; short *sp; {
+       register i;
+
+       for (i=0;i<MAXREGS+MAXTOKENS;i++)
+           if(BIT(from.in_set,i))
+               if (!subset(sp,posmoves[i],SETSIZE))
+                       return(0);
+       return(1);
+}
+
+existalmove(from,prpno) iocc_t from; {
+       short s[SETSIZE];
+       register i;
+       
+       for (i=0;i<SETSIZE;i++)
+               s[i] = i<SZOFSET(MAXREGS) ? l_props[prpno].pr_regset[i] : 0;
+       return(existmove(from,s));
+}
+
+struct varinfo *gen_move(from,to) iocc_t from,to; {
+       register struct varinfo *vp;
+
+       if (existmove(from,to.in_set)==0) {
+               error("No such move defined");
+               return(VI_NULL);
+       }
+       NEW(vp,struct varinfo);
+       vp->vi_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;i<SETSIZE;i++)
+               postests[i] |= l_sets[tp->t_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;i<SETSIZE;i++)
+               sp[i] |= l_sets[s].set_val[i];
+}
+
+checkstacking(sp) register short *sp; {
+       register i;
+       register short *chkset;
+       char *warn;
+
+       if (subset(sp,ustackset.set_val,SETSIZE))
+               return;
+       chkset = ustackset.set_val; warn = "";
+       for (i=1;i<nregs;i++)
+               if (BIT(sp,i) && !BIT(chkset,i))
+                       error("No %sstacking rule for register %s",warn,
+                               l_regs[i].ri_name);
+       for(;i<nregs+MAXTOKENS;i++)
+               if (BIT(sp,i) && !BIT(chkset,i))
+                       error("No %sstacking rule for token %s",warn,
+                               l_tokens[i-nregs]->tk_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;i<SETSIZE;i++)
+                       unstackset.set_val[i] |= in.in_set[i];
+       freevi(rp);
+}
+
+checkunstacking(setno) {
+       register short *sp;
+       register i;
+       short hallset[SETSIZE];
+       
+       sp = l_sets[setno].set_val;
+       for (i=0;i<SETSIZE;i++)
+               hallset[i]=sp[i]&unstackset.set_val[i];
+       nexthall(hallset);
+}
+
+int nsplit,maxsplit;
+c2_t l_split[MAXSPLCOERC];
+
+n_split(ti,be,al,ge,rp,n) struct varinfo *al,*ge,*rp; {
+       register c2_p c2p;
+       register i;
+       register struct varinfo *vi;
+
+       NEXT(nsplit,MAXSPLCOERC,"Splitting coercions");
+       c2p = &l_split[nsplit-1];
+       if (n>MAXSPLIT) {
+               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; i<n; i++,vi=vi->vi_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 (executable)
index 0000000..31fc0b4
--- /dev/null
@@ -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 (file)
index 0000000..85289a7
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include "param.h"
+#include "expr.h"
+#include <em_spec.h>
+#include <em_flag.h>
+
+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 (file)
index 0000000..c3bf854
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include <stdio.h>
+
+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 (file)
index 0000000..77dd1a0
--- /dev/null
@@ -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 <cgg_cg.h>
+#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;i<SZOFSET(MAXREGS);i++)
+               result.ex_regset[i] = 0;
+       BIS(result.ex_regset,regno);
+       return(result);
+}
+
+expr_t ident_expr(name) char *name; {
+       register symbol *sy_p;
+
+       sy_p = lookup(name,symany,mustexist);
+       if (sy_p->sy_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;i<SZOFSET(MAXREGS);i++)
+               regset[i]=0;
+       for (i=1;i<nregs;i++)   if (BIT(sp,i)) {
+               if(subreg) {
+                       rp = &l_regs[i];
+                       if (rp->ri_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(;i<nregs+MAXTOKENS;i++) if(BIT(sp,i))
+               error("Set contains %s, which is not a register",
+                       l_tokens[i-nregs]->tk_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;i<nregs;i++) if (BIT(sp,i)) {
+               error("Set in %s contains %s, which is not a token",
+                       appearance,l_regs[i].ri_name);
+               break;
+       }
+       for (i=0;i<SZOFSET(MAXREGS);i++)
+               regset[i] = 0;
+       for (i=nregs;i<nregs+MAXTOKENS;i++) if (BIT(sp,i)) {
+               tp = l_tokens[i-nregs];
+               for(j=0;j<MAXATT &&
+                       (tp->tk_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;k<SZOFSET(MAXREGS);k++)
+                                               regset[k] |=
+                                                   l_props[tp->tk_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;i<SETSIZE;i++)
+               localset.set_val[i] = i<SZOFSET(MAXREGS) ? sp[i] : 0;
+       subregset(localset.set_val,subreg,result.ex_regset);
+       result.ex_typ = TYPREG;
+       result.ex_index = ex_lookup(EX_ALLREG,all_no+1,subreg);
+       return(result);
+}
+
+eq2expr(e1,e2) expr_t e1,e2; {
+
+       if (e1.ex_typ != e2.ex_typ)
+               error("Expressions around == should have equal type");
+       switch (e1.ex_typ) {
+       default: assert(0);
+       case TYPBOOL:
+               error("== on booleans not implemented");
+       case TYPINT:
+               return(EX_NCPEQ);
+       case TYPADDR:
+               return(EX_SCPEQ);
+       case TYPREG:
+               return(EX_RCPEQ);
+       }
+}
+
+ne2expr(e1,e2) expr_t e1,e2; {
+
+       if (e1.ex_typ != e2.ex_typ)
+               error("Expressions around != should have equal type");
+       switch (e1.ex_typ) {
+       default: assert(0);
+       case TYPBOOL:
+               error("!= on booleans not implemented");
+       case TYPINT:
+               return(EX_NCPNE);
+       case TYPADDR:
+               return(EX_SCPNE);
+       case TYPREG:
+               return(EX_RCPNE);
+       }
+}
+
+expr_t sum_expr(e1,e2) expr_t e1,e2; {
+       int operator,op1,op2;
+       expr_t result;
+
+       operator = EX_CAT; op1 = e1.ex_index; op2 = e2.ex_index;
+       if (e1.ex_typ==e2.ex_typ) {
+               result.ex_typ = e1.ex_typ;
+               if (e1.ex_typ == TYPINT)
+                       operator = EX_PLUS;
+               else if (e1.ex_typ != TYPADDR)
+                       error("+ is not implemented on this type");
+       } else {
+               result.ex_typ = TYPADDR;
+               if (e1.ex_typ != TYPADDR) {
+                       if (e1.ex_typ!=TYPINT)
+                               error("Wrong left operand of +");
+                       op1 = ex_lookup(EX_TOSTRING,op1,0);
+               }
+               if (e2.ex_typ != TYPADDR) {
+                       if (e2.ex_typ!=TYPINT)
+                               error("Wrong right operand of +");
+                       op2 = ex_lookup(EX_TOSTRING,op2,0);
+               }
+       }
+       result.ex_index=ex_lookup(operator,op1,op2);
+       return(result);
+}
+
+expr_t iextoaddr(e) expr_t e; {
+       expr_t result;
+
+       result.ex_typ = TYPADDR;
+       result.ex_index = ex_lookup(EX_TOSTRING,e.ex_index,0);
+       return(result);
+}
+
+expr_t regvar_expr(e,regtyp) expr_t e; {
+       expr_t result;
+       register i;
+       
+       result = make_expr(TYPREG,EX_REGVAR,i_expr(e),0);
+       for(i=0;i<SZOFSET(MAXREGS);i++)
+               result.ex_regset[i]=0;
+       for(i=0;i<nregvar[regtyp];i++)
+               BIS(result.ex_regset,rvnumbers[regtyp][i]);
+       return(result);
+}
+               
+/*
+ * Node table lookup part
+ */
+
+node_t nodes[MAXNODES];
+int nnodes=0;
+
+initnodes() {
+
+       nodes[0].ex_operator = EX_CON;
+       nodes[0].ex_lnode = 0;
+       nodes[0].ex_rnode = 0;
+       nnodes++;
+}
+
+ex_lookup(operator,lnode,rnode) {
+       register node_p p;
+
+       for(p=nodes+1;p< &nodes[nnodes];p++) {
+               if (p->ex_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 (file)
index 0000000..94eb550
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "set.h"
+#include <stdio.h>
+
+/*
+ * 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<SETSIZE;i++)
+               hallsets[nhallsets][i] = sp[i];
+       nhallsets++;
+}
+
+card(sp) register short *sp; {
+       register sum,i;
+       
+       sum=0;
+       for(i=0;i<8*SETSIZE;i++)
+               if (BIT(sp,i))
+                       sum++;
+       return(sum);
+}
+
+checkhall() {
+
+       assert(nhallsets>=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;i++)
+                       if (card(hallsets[i])>=nhallsets) {
+                               for (j=i+1;j<nhallsets;j++)
+                                       for(k=0;k<SETSIZE;k++)
+                                               hallsets[j-1][k] =
+                                                       hallsets[j][k];
+                               nhallsets--;
+                               ok = 1;
+                               break;
+                       }
+       } while (ok);
+       
+       /*
+        * Now all sets have cardinality < nhallsets
+        */
+       
+       hallfreq[nhallsets][1]++;
+       ok=recurhall(nhallsets,hallsets);
+       nhallsets = -1;
+       return(ok);
+}
+
+recurhall(nhallsets,hallsets) short hallsets[][SETSIZE]; {
+       short copysets[MAXHALL][SETSIZE];
+       short setsum[SETSIZE];
+       register i,j,k,ncopys;
+       
+       /*
+        * First check cardinality of union of all
+        */
+       for(k=0;k<SETSIZE;k++)
+               setsum[k]=0;
+       for(i=0;i<nhallsets;i++)
+               unite(hallsets[i],setsum);
+       if (card(setsum)<nhallsets)
+               return(0);
+       /*
+        * Now check the hall property of everything but one set,
+        * for all sets
+        */
+       for(i=0;i<nhallsets;i++) {
+               ncopys=0;
+               for(j=0;j<nhallsets;j++) if (j!=i) {
+                       for(k=0;k<SETSIZE;k++)
+                               copysets[ncopys][k] = hallsets[j][k];
+                       ncopys++;
+               }
+               assert(ncopys == nhallsets-1);
+               if (!recurhall(ncopys,copysets))
+                       return(0);
+       }
+       return(1);
+}
+
+unite(sp,into) register short *sp,*into; {
+       register i;
+       
+       for(i=0;i<SETSIZE;i++)
+               into[i] |= sp[i];
+}
+
+/*
+ * Limerick (rot13)
+ *
+ * N zngurzngvpvna anzrq Unyy
+ * Unf n urknurqebavpny onyy,
+ *     Naq gur phor bs vgf jrvtug
+ *     Gvzrf uvf crpxre'f, cyhf rvtug
+ * Vf uvf cubar ahzore -- tvir uvz n pnyy..
+ */
diff --git a/util/ncgg/instruct.c b/util/ncgg/instruct.c
new file mode 100644 (file)
index 0000000..ac6aff4
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include "param.h"
+#include "instruct.h"
+#include "pseudo.h"
+#include "varinfo.h"
+#include "set.h"
+#include "expr.h"
+#include "iocc.h"
+#include <cgg_cg.h>
+#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;bitno<nregs+ntokens;bitno++)
+               if (BIT(sp,bitno))
+                       return(0);
+       return(1);
+}
+
+makescratch(argno) {
+       set_t s;
+
+       if (tokpatro[argno-1])
+               error("Instruction destroys %%%d, not allowed here",argno);
+       s = l_sets[tokpatset[argno-1]];
+       BIC(s.set_val,0);
+       tokpatset[argno-1] = setlookup(s);
+}
+
+struct varinfo *gen_inst(ident,star) char *ident; {
+       register struct varinfo *vi,*retval,*eravi;
+       register instr_p ip;
+       register struct operand *op;
+       register i;
+       register inst_p insta;
+       
+       if (star && !inproc)
+               error("Variable instruction only allowed inside proc");
+       for (ip=l_instr;ip<l_instr+ninstr;ip++) {
+               if(strcmp(ident,ip->i_name))
+                       continue;
+               if (ip->i_nops!=niops)
+                       continue;
+               for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_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;i<niops;i++) {
+               NEW(vi->vi_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;i<niops;i++,op=op->o_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 (file)
index 0000000..357c644
--- /dev/null
@@ -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 <cgg_cg.h>
+#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;i<SETSIZE;i++)
+                       result.in_set[i] = l_sets[tokpatset[tokarg-1]].set_val[i];
+       else {
+               for (i=0;i<SETSIZE;i++)
+                       result.in_set[i] = 0;
+               subregset(l_sets[tokpatset[tokarg-1]].set_val,subreg,result.in_set);
+       }
+       return(result);
+}
+
+iocc_t tokm_iocc(tokarg,ident) char *ident; {
+       iocc_t result;
+       inst_t insta;
+       register i;
+       char app[100];
+       int dummy;
+       
+       sprintf(app,"%%%d.%s",tokarg,ident);
+       for(i=0;i<SETSIZE;i++)
+               result.in_set[i] = 0;
+       insta.in_which = IN_MEMB;
+       insta.in_info[0] = tokarg;
+       insta.in_info[1] = 1+membset(tokpatset[tokarg-1],ident,result.in_set,
+                                   app,TYPREG,&dummy);
+       result.in_index = instalookup(insta,2);
+       return(result);
+}
+       
+iocc_t ident_iocc(ident) char *ident; {
+       iocc_t result;
+       inst_t insta;
+       register i;
+       register symbol *sy_p;
+
+       for(i=0;i<SETSIZE;i++)
+               result.in_set[i] = 0;
+       insta.in_which = IN_RIDENT;
+       sy_p = lookup(ident,symreg,mustexist);
+       insta.in_info[0] = sy_p->sy_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;i<SETSIZE;i++)
+               localset.set_val[i] = i<SZOFSET(MAXREGS) ? sp[i] : 0;
+       for(i=0;i<SETSIZE;i++)
+               result.in_set[i] = 0;
+       insta.in_which = IN_ALLOC;
+       insta.in_info[0] = all_no;
+       insta.in_info[1] = subreg;
+       subregset(localset.set_val,subreg,result.in_set);
+       result.in_index = instalookup(insta,2);
+       return(result);
+}
+
+iocc_t descr_iocc(ident) char *ident; {
+       iocc_t result;
+       inst_t insta;
+       register symbol *sy_p;
+       register token_p tp;
+       register i;
+       int typerr;
+
+       for(i=0;i<SETSIZE;i++)
+               result.in_set[i] = 0;
+       sy_p = lookup(ident,symtok,mustexist);
+       tp = l_tokens[sy_p->sy_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;i<MAXATT;i++) {
+               if (tp->tk_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;i<ninstances;i++) {
+               if (insta.in_which != l_instances[i].in_which)
+                       continue;
+               for(j=0;j<=MAXATT;j++)
+                       if (insta.in_info[j]!= l_instances[i].in_info[j])
+                               goto cont;
+               return(i);
+           cont:;
+       }
+       NEXT(ninstances,MAXINSTANCES,"Instances");
+       l_instances[i] = insta;
+       return(i);
+}
+
+       
+                               
diff --git a/util/ncgg/keywords b/util/ncgg/keywords
new file mode 100644 (file)
index 0000000..48f6019
--- /dev/null
@@ -0,0 +1,48 @@
+# $Header$
+#
+ADDR   ADDR
+COERCIONS      COERCIONS
+INSTRUCTIONS   INSTRUCTIONS
+INT    INT
+MOVES  MOVES
+PATTERNS       PATTERNS
+PROPERTIES     PROPERTIES
+REGISTERS      REGISTERS
+SETS   SETS
+SIZEFACTOR     SIZEFACTOR
+STACK  STACK
+STACKINGRULES  STACKINGRULES
+TESTS  TESTS
+TIMEFACTOR     TIMEFACTOR
+TOKENS TOKENS
+call   CALL
+cost   COST
+defined        DEFINED
+exact  EXACT
+example        EXAMPLE
+from   FROM
+gen    GEN
+highw  HIGHW
+inreg  INREG
+kills  KILLS
+leaving        LEAVING
+loww   LOWW
+move   MOVE
+pat    PAT
+proc   PROC
+reg_any        REG_ANY
+reg_float      REG_FLOAT
+reg_loop       REG_LOOP
+reg_pointer    REG_POINTER
+regvar REGVAR
+return RETURN
+reusing        REUSING
+rom    ROM
+samesign       SAMESIGN
+sfit   SFIT
+test   TEST
+to     TO
+ufit   UFIT
+uses   USES
+with   WITH
+yields YIELDS
diff --git a/util/ncgg/lookup.c b/util/ncgg/lookup.c
new file mode 100644 (file)
index 0000000..8b7ecf3
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include "assert.h"
+#include "param.h"
+#include "lookup.h"
+
+char *myalloc();
+char *mystrcpy();
+
+symbol dumsym; /* dummy to return in case of error */
+
+symbol *lookup(name,type,style)
+char *name;
+symtype type;
+lookupstyle style;
+{
+       symbol *sy_p,**sy_pp;
+
+       for (sy_pp = &symhash[hashvalue(name)];(sy_p= *sy_pp) != 0;sy_pp= &sy_p->sy_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<<i;
+       return(sum%NSYMHASH);
+}
diff --git a/util/ncgg/main.c b/util/ncgg/main.c
new file mode 100644 (file)
index 0000000..5ab322b
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include <stdio.h>
+
+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 (executable)
index 0000000..31e2e20
--- /dev/null
@@ -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 (file)
index 0000000..7dbf5f3
--- /dev/null
@@ -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 <stdio.h>
+#include <ctype.h>
+#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 <cgg_cg.h>
+#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<empatlen;i++)
+                       patbyte(emmnem[i]);
+               pat(empatexpr);
+       }
+       if (callproc==0) {
+               patbyte(npatterns);
+               for(i=0;i<npatterns;i++)
+                       pat(patindex[i]);
+       } else {
+               patbyte(0);
+               pat(callproc);
+               pat(procarg[0]);
+               pat(procarg[1]);
+       }
+}
+
+pat(n) {
+
+       assert(n>=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;
+               }
+               patlen = i;
+               hashvalue = 0;
+               switch(patlen) {
+               default:        /* 3 or more */
+                       hashvalue = (hashvalue<<4)^(*tp++&BMASK);
+               case 2:
+                       hashvalue = (hashvalue<<4)^(*tp++&BMASK);
+               case 1:
+                       hashvalue = (hashvalue<<4)^(*tp++&BMASK);
+               }
+               assert(hashvalue!= ILLHASH);
+               i=index;
+               index = (bp[PO_NEXT]&BMASK)|(bp[PO_NEXT+1]<<BSHIFT);
+               bp[PO_HASH] = hashvalue>>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 <cgg_cg.h>\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<nregs;i++)
+               fprintf(ctable,"\t%d,\n",l_regs[i].ri_class);
+       fprintf(ctable,"};\n\nstruct reginfo machregs[] = {\n{0},\n");
+       for (i=1;i<nregs;i++) {
+               fprintf(ctable,"{%d,%d",strlookup(l_regs[i].ri_repr),
+                       l_regs[i].ri_size);
+               if (maxmembers!=0) {
+                       fprintf(ctable,",{");
+                       for(j=0;j<2;j++)
+                               fprintf(ctable,"%d,",l_regs[i].ri_memb[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<SZOFSET(MAXREGS);j++)
+                               rset[j]=0;
+                       BIS(rset,i);
+                       do {
+                           ready=1;
+                           for (j=1;j<nregs;j++)
+                               if (BIT(rset,j))
+                                   for (k=0;k<2;k++)
+                                       if ((t=l_regs[j].ri_memb[k])!=0) {
+                                           if (BIT(rset,t)==0)
+                                               ready=0;
+                                           BIS(rset,t);
+                                       }
+                       } while (!ready);
+                       do {
+                           ready=1;
+                           for (j=1;j<nregs;j++)
+                               for (k=0;k<2;k++)
+                                   if ((t=l_regs[j].ri_memb[k])!=0)
+                                       if (BIT(rset,t)) {
+                                               if (BIT(rset,j)==0)
+                                                   ready=0;
+                                               BIS(rset,j);
+                                       }
+                       } while (!ready);
+                       fprintf(ctable,"},{");
+                       for (j=0;j<SZOFSET(nregs);j++)
+                               fprintf(ctable,"0%o,",rset[j]&0xFFFF);
+                       fprintf(ctable,"}");
+               }
+               fprintf(ctable,",%d",l_regs[i].ri_rregvar>=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;j<nregvar[i];j++)
+                       fprintf(ctable,"%d,",rvnumbers[i][j]);
+               fprintf(ctable,"};\n");
+       }
+       fprintf(ctable,"\nint *rvnumbers[] = {\n");
+       for (i=0;i<4;i++)
+               if (nregvar[i]>0)
+                       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;tokno<ntokens;tokno++) {
+               tp = l_tokens[tokno];
+               fprintf(ctable,"{%d,{%d,%d},{",
+                       tp->tk_size, tp->tk_cost.ct_space, tp->tk_cost.ct_time);
+               for(i=0;i<maxtokensize;i++)
+                       fprintf(ctable,"%d,",typeconv(tp->tk_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;i<nstrings;i++) {
+               p= l_strings[i];
+               fprintf(ctable,"\t\"");
+               while ((c= (*p++&0377))!=0)
+                       fprintf(ctable, !isascii(c) || iscntrl(c) ? "\\%03o" : "%c",c);
+               fprintf(ctable,"\",\n");
+       }
+       fprintf(ctable,"};\n\n");
+}
+
+outsets() {
+       register i;
+       register set_p sp;
+
+       fprintf(ctable,"set_t machsets[] = {\n");
+       for (sp=l_sets;sp< &l_sets[nsets]; sp++) {
+               fprintf(ctable,"{%3d,{",sp->set_size);
+               for (i=0;i<setsize;i++)
+                       fprintf(ctable,"0x%04x,",sp->set_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;i<maxsplit;i++)
+                       fprintf(ctable,"%d,",cp->c2_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;propno<nprops;propno++) {
+               fprintf(ctable,"struct reginfo *rlist%02d[] = {\n",propno);
+               for(regno=1;regno<nregs;regno++)
+                       if (BIT(l_props[propno].pr_regset,regno))
+                               fprintf(ctable,"&machregs[%d],\n",regno);
+               fprintf(ctable,"0\n};\n");
+       }
+       fprintf(ctable,"struct reginfo **reglist[] = {\n");
+       for(propno=0;propno<nprops;propno++)
+               fprintf(ctable,"rlist%02d,\n",propno);
+       fprintf(ctable,"};\n\n");
+}
+
+outconsts() {
+
+       fprintf(ctable,"unsigned cc1 = %u;\n",fc1);
+       fprintf(ctable,"unsigned cc2 = %u;\n",fc2);
+       fprintf(ctable,"unsigned cc3 = %u;\n",fc3);
+       fprintf(ctable,"unsigned cc4 = %u;\n",fc4);
+}
+
+cdef(s,n) char *s; {
+
+       fprintf(htable,"#define %s %d\n",s,n);
+}
+
+passon(s) char *s; {
+       char buf[32];
+
+       sprintf(buf,"T%s",s);
+       cdef(buf,cmustbeset(s));
+}
+
+outdefs() {
+       register symbol *sy_p;
+       extern int maxempatlen,maxrule;
+       char *wrdfmt;
+
+       passon("EM_WSIZE");
+       passon("EM_PSIZE");
+       passon("EM_BSIZE");
+       if ((sy_p=lookup("FORMAT",symsconst,justlooking))!=0)
+               wrdfmt = l_strings[sy_p->sy_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;i<npatbytes;i++) {
+               fprintf(ctable,"%d,%c",pattern[i]&BMASK,i%16==15 ? '\n' : ' ');
+       }
+       fprintf(ctable,"};\n\n");
+       fprintf(ctable,"int pathash[256]={\n");
+       for(i=0;i<256;i++) {
+               fprintf(ctable,"%d,%c",pathash[i]&0xFFFF,i%10==9 ? '\n' : ' ');
+       }
+       fprintf(ctable,"};\n");
+}
+
+finishio() {
+       extern int nregs;
+
+       finishcode();
+       hashpatterns();
+       setsize = SZOFSET(nregs+ntokens);
+       outdefs();
+       outincludes();
+       outregs();
+       outtokens();
+       outenodes();
+       outstrings();
+       outsets();
+       outinstances();
+       outmoves();
+       outtests();
+       outstacks();
+       if (nsplit>0)
+               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 (startline<MAXSOURCELINES) {
+                       if (startline>maxline)
+                               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;i<tokpatlen;i++)
+                       codeint(tokpatset[i]);
+               codenl();
+       } else if (stackcoerc)
+               code8nl(DO_COERC);
+       if (optstack) {
+               code53(DO_REMOVE,0);
+               codeint(allsetno);
+               codenl();
+       }
+       /* The kills */
+       for (vp=kills;vp!=0;vp=vp->vi_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;i<nops;i++) {
+                               codeint(vivp->vi_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 (file)
index 0000000..11cff75
--- /dev/null
@@ -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 (file)
index 0000000..54e3f1f
--- /dev/null
@@ -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 <cgg_cg.h>
+#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;i<SETSIZE;i++)
+                       if (p->set_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;i<SETSIZE;i++)
+               s.set_val[i]=0;
+       for(i=0;i<nregs+ntokens;i++)
+               BIS(s.set_val,i);
+       s.set_size = 0;
+       allsetno = setlookup(s);
+       n_set("ALL",allsetno);
+}
+
+set_t emptyset;
+
+set_t ident_to_set(name) char *name; {
+       register symbol *sy_p;
+       register i;
+       register struct propinfo *pp;
+       int bitno;
+       set_t result;
+
+       sy_p = lookup(name,symany,mustexist);
+       switch(sy_p->sy_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;i<SZOFSET(MAXREGS);i++)
+                       result.set_val[i] = pp->pr_regset[i];
+               BIS(result.set_val,0);
+               for (;i<SETSIZE;i++)
+                       result.set_val[i] = 0;
+               break;
+       case symtok:
+               bitno = sy_p->sy_value.syv_tokno+nregs;
+               for (i=0;i<SETSIZE;i++)
+                       result.set_val[i] = 0;
+               BIS(result.set_val,bitno);
+               result.set_size = l_tokens[sy_p->sy_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<SETSIZE;i++)
+               result.set_val[i] = s1.set_val[i] & s2.set_val[i];
+       return(result);
+}
+
+set_t setsum(s1,s2) set_t s1,s2; {
+       set_t result;
+       register i;
+
+       if (s1.set_size == s2.set_size)
+               result.set_size = s1.set_size;
+       else
+               result.set_size = 0;
+       for(i=0;i<SETSIZE;i++)
+               result.set_val[i] = s1.set_val[i] | s2.set_val[i];
+       return(result);
+}
+
+set_t setdiff(s1,s2) set_t s1,s2; {
+       set_t result;
+       register i;
+
+       if (s1.set_size == s2.set_size)
+               result.set_size = s1.set_size;
+       else
+               result.set_size = 0;
+       for(i=0;i<SETSIZE;i++)
+               result.set_val[i] = s1.set_val[i] & ~ s2.set_val[i];
+       return(result);
+}
diff --git a/util/ncgg/strlookup.c b/util/ncgg/strlookup.c
new file mode 100644 (file)
index 0000000..4e41786
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include "param.h"
+
+int nstrings=0;
+char *l_strings[MAXSTRINGS];
+
+strlookup(str) char *str; {
+       register i;
+       extern char *mystrcpy();
+
+       for(i=0;i<nstrings;i++)
+               if (strcmp(str,l_strings[i])==0)
+                       return(i);
+       NEXT(nstrings,MAXSTRINGS,"String table");
+       l_strings[i] = mystrcpy(str);
+       return(i);
+}
diff --git a/util/ncgg/subr.c b/util/ncgg/subr.c
new file mode 100644 (file)
index 0000000..6ad80f4
--- /dev/null
@@ -0,0 +1,382 @@
+#ifndef NORCSID
+static char rcsid[]= "$Header$";
+#endif
+
+#include "param.h"
+#include "reg.h"
+#include "lookup.h"
+#include "property.h"
+#include "expr.h"
+#include "set.h"
+#include "varinfo.h"
+#include "instruct.h"
+#include "token.h"
+#include "regvar.h"
+#include <cgg_cg.h>
+#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;i<MAXATT && vip!=0;i++,vip=vip->vi_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(;i<MAXATT;i++)
+               tp->tk_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;i<MAXATT;i++) {
+                                       if (strcmp(vip->vi_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;i<nregs+ntokens;i++)
+               if (BIT(s,i) && l_tokens[i-nregs]->tk_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;i<SETSIZE;i++)
+               hallset[i] = i<SZOFSET(MAXREGS) ? l_props[n].pr_regset[i] : 0;
+       nexthall(hallset);
+}
+
+n_reg(name,printstring,nmemb,member1,member2) char *name,*printstring; {
+       register symbol *sy_p;
+       register reginfo *ri_p;
+       int regno;
+
+       sy_p = lookup(name,symreg,newsymbol);
+       sy_p->sy_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;i<VI_NSTR;i++)
+               if (vip->vi_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 (value<lwb || value>upb)
+               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;i<setsize;i++)
+               if ( (sp1[i] | sp2[i]) != sp2[i])
+                       return(0);
+       return(1);
+}
+
+vilength(vip) register struct varinfo *vip; {
+       register l=0;
+
+       while(vip!=0) {
+               vip=vip->vi_next;
+               l++;
+       }
+       return(l);
+}
diff --git a/util/ncgg/var.c b/util/ncgg/var.c
new file mode 100644 (file)
index 0000000..97ba265
--- /dev/null
@@ -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 <cgg_cg.h>
+
+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];