*** empty log message ***

This commit is contained in:
sater 1985-01-08 09:59:28 +00:00
parent 5edf93d2de
commit 72b83cca59
20 changed files with 4075 additions and 0 deletions

171
util/ncgg/Makefile Normal file
View file

@ -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

992
util/ncgg/cgg.y Normal file
View file

@ -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"

249
util/ncgg/coerc.c Normal file
View file

@ -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);
}

22
util/ncgg/cvtkeywords Executable file
View file

@ -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

73
util/ncgg/emlookup.c Normal file
View file

@ -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);
}
}

54
util/ncgg/error.c Normal file
View file

@ -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);
}

311
util/ncgg/expr.c Normal file
View file

@ -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);
}

155
util/ncgg/hall.c Normal file
View file

@ -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..
*/

179
util/ncgg/instruct.c Normal file
View file

@ -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);
}

187
util/ncgg/iocc.c Normal file
View file

@ -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);
}

48
util/ncgg/keywords Normal file
View file

@ -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

65
util/ncgg/lookup.c Normal file
View file

@ -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);
}

53
util/ncgg/main.c Normal file
View file

@ -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);
}

15
util/ncgg/makedepend Executable file
View file

@ -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

837
util/ncgg/output.c Normal file
View file

@ -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);
}

99
util/ncgg/scan.l Normal file
View file

@ -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;
}

118
util/ncgg/set.c Normal file
View file

@ -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);
}

20
util/ncgg/strlookup.c Normal file
View file

@ -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);
}

382
util/ncgg/subr.c Normal file
View file

@ -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);
}

45
util/ncgg/var.c Normal file
View file

@ -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];