*** empty log message ***
This commit is contained in:
parent
5edf93d2de
commit
72b83cca59
171
util/ncgg/Makefile
Normal file
171
util/ncgg/Makefile
Normal 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
992
util/ncgg/cgg.y
Normal 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
249
util/ncgg/coerc.c
Normal 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
22
util/ncgg/cvtkeywords
Executable 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
73
util/ncgg/emlookup.c
Normal 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
54
util/ncgg/error.c
Normal 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
311
util/ncgg/expr.c
Normal 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
155
util/ncgg/hall.c
Normal 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
179
util/ncgg/instruct.c
Normal 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
187
util/ncgg/iocc.c
Normal 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
48
util/ncgg/keywords
Normal 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
65
util/ncgg/lookup.c
Normal 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
53
util/ncgg/main.c
Normal 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
15
util/ncgg/makedepend
Executable 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
837
util/ncgg/output.c
Normal 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
99
util/ncgg/scan.l
Normal 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
118
util/ncgg/set.c
Normal 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
20
util/ncgg/strlookup.c
Normal 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
382
util/ncgg/subr.c
Normal 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
45
util/ncgg/var.c
Normal 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];
|
Loading…
Reference in a new issue