Initial revision
authorbruce <none@none>
Thu, 15 Jan 1987 18:12:26 +0000 (18:12 +0000)
committerbruce <none@none>
Thu, 15 Jan 1987 18:12:26 +0000 (18:12 +0000)
14 files changed:
modules/src/em_opt/Makefile [new file with mode: 0644]
modules/src/em_opt/aux.c [new file with mode: 0644]
modules/src/em_opt/findworst.c [new file with mode: 0644]
modules/src/em_opt/initlex.c [new file with mode: 0644]
modules/src/em_opt/mkcalls.c [new file with mode: 0644]
modules/src/em_opt/nopt.c [new file with mode: 0644]
modules/src/em_opt/nopt.h [new file with mode: 0644]
modules/src/em_opt/outcalls.c [new file with mode: 0644]
modules/src/em_opt/outputdfa.c [new file with mode: 0644]
modules/src/em_opt/parser.g [new file with mode: 0644]
modules/src/em_opt/parser.h [new file with mode: 0644]
modules/src/em_opt/patterns [new file with mode: 0644]
modules/src/em_opt/pseudo.r [new file with mode: 0644]
modules/src/em_opt/syntax.l [new file with mode: 0644]

diff --git a/modules/src/em_opt/Makefile b/modules/src/em_opt/Makefile
new file mode 100644 (file)
index 0000000..c8d1a55
--- /dev/null
@@ -0,0 +1,63 @@
+# $Header$
+EMHOME=/usr/em
+MODLIB=$(EMHOME)/modules/lib
+PARSERLIB=$(EMHOME)/lib/em_data.a $(MODLIB)/libprint.a $(MODLIB)/liballoc.a\
+       $(MODLIB)/libstring.a $(MODLIB)/libsystem.a
+HOWMUCH=head -10
+LEXLIB=-ll
+INCLDIR=-I$(EMHOME)/h -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg
+PREFLAGS=$(INCLDIR) -DPRIVATE=static -DDEBUG
+PROFFLAG=-O
+CFLAGS=$(PREFLAGS) $(PROFFLAG)
+LLOPT=
+GFILES=parser.g
+POFILES=parser.o syntax.o outputdfa.o outcalls.o findworst.o outputrepl.o\
+       initlex.o Lpars.o 
+NOFILES=nopt.o dfa.o trans.o incalls.o psuedo.o aux.o mkcalls.o
+GENFILES=Lpars.h Lpars.c parserdummy parser.c syntax.c dfadummy\
+       dfa.c dfa.c.save trans.c trans.c.save incalls.c incalls.c.save
+
+all:   libopt.a
+
+libopt.a:      dfadummy $(NOFILES)
+       ar rc libopt.a $(NOFILES)
+       ranlib libopt.a
+
+dfadummy: patterns parser
+       -mv dfa.c dfa.c.save
+       -mv trans.c trans.c.save
+       -mv incalls.c incalls.c.save
+       -/lib/cpp patterns | $(HOWMUCH) >/tmp/patts
+       parser </tmp/patts
+       -rm /tmp/patts
+       -if cmp -s dfa.c dfa.c.save; then mv dfa.c.save dfa.c; else exit 0; fi
+       -if cmp -s trans.c trans.c.save; then mv trans.c.save trans.c; else exit 0; fi
+       -if cmp -s incalls.c incalls.c.save; then mv incalls.c.save incalls.c; else exit 0; fi
+       touch dfadummy
+
+parser: parserdummy $(POFILES) $(PARSERLIB)
+       $(CC) -o parser $(LDFLAGS) $(POFILES) $(PARSERLIB) $(LEXLIB)
+
+parserdummy:   $(GFILES)
+       LLgen $(LLOPT) $(GFILES)
+       touch parserdummy
+
+clean:
+       rm -f $(NOFILES) $(POFILES) $(GENFILES) parser
+
+nopt.o:        nopt.h
+dfa.o: nopt.h
+aux.o: nopt.h
+trans.o:       nopt.h
+psuedo.o:      nopt.h
+incalls.o:     nopt.h
+mkcalls.o:     nopt.h
+
+parser.o:      Lpars.h parser.h
+Lpars.o:       Lpars.h
+syntax.o:      syntax.l parser.h Lpars.h
+outputdfa.o:   parser.h Lpars.h
+outcalls.o:    parser.h
+findworst.o:   parser.h
+outputrepl.o:  parser.h Lpars.h
+initlex.o:     parser.h
diff --git a/modules/src/em_opt/aux.c b/modules/src/em_opt/aux.c
new file mode 100644 (file)
index 0000000..bcb54a0
--- /dev/null
@@ -0,0 +1,88 @@
+/* $Header$ */
+#include "nopt.h"
+
+rotate(w,amount)
+       int w, amount;
+{
+       long highmask, lowmask;
+       highmask = (long)(-1) << amount;
+       lowmask = ~highmask;
+       if(WSIZE!=4)
+               highmask &= (WSIZE==2)?0xFFFF:0xFF;
+       return(((w<<amount)&highmask) | ((w >> (8*WSIZE-amount))&lowmask));
+}
+
+samesign(a,b)
+       int a, b;
+{
+       return( (a ^ b) >= 0);
+}
+
+sfit(val,nbits)
+       int val, nbits;
+{
+       long mask = 0;
+       int i;
+       for(i=nbits-1;i<8*sizeof(mask);i++)
+               mask |= (1<<i);
+       return(((val&mask) == 0) | (val&mask)==mask);
+}
+
+ufit(val, nbits)
+       int val, nbits;
+{
+       long mask = 0;
+       int i;
+       for(i=nbits;i<8*sizeof(mask);i++)
+               mask |= (1<<i);
+       return((val&mask) == 0);
+}
+
+sameext(a1,a2)
+       struct instr *a1, *a2;
+{
+       if(a1->argtype != a2->argtype) return(0);
+       switch(a1->argtype) {
+       case cst_ptyp:
+               return(a1->acst == a2->acst);
+       case sof_ptyp:
+               if(a1->asoff != a2->asoff) return(0);
+               return(strcmp(a1->adnam,a2->adnam)==0);
+       case nof_ptyp:
+               if(a1->anoff != a2->anoff) return(0);
+               return(a1->adlb == a2->adlb);
+       default:
+               fatal("illegal type (%d) to sameext!",a1->argtype);
+       }
+}
+
+samenam(a1,a2)
+       struct instr *a1, *a2;
+{
+       if(a1->argtype != a2->argtype) return(0);
+       switch(a1->argtype) {
+       case cst_ptyp:
+               return(1);
+       case sof_ptyp:
+               return(strcmp(a1->adnam,a2->adnam)==0);
+       case nof_ptyp:
+               return(a1->adlb == a2->adlb);
+       default:
+               fatal("illegal type (%d) to samenam!",a1->argtype);
+       }
+}
+
+offset(a)
+       struct instr *a;
+{
+       switch(a->argtype) {
+       case cst_ptyp:
+               return(a->acst);
+       case sof_ptyp:
+               return(a->asoff);
+       case nof_ptyp:
+               return(a->anoff);
+       default:
+               fatal("illegal type (%d) to offset!",a->argtype);
+       }
+}
diff --git a/modules/src/em_opt/findworst.c b/modules/src/em_opt/findworst.c
new file mode 100644 (file)
index 0000000..6192fae
--- /dev/null
@@ -0,0 +1,145 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "parser.h"
+
+#define UPDATEWORST(backups) if(backups>mostbackups) mostbackups = backups;
+
+findworst(state,repl)
+       int state;
+       struct mnems repl;
+{
+       /*
+       /* Find the pattern that requires the most backup of output queue.
+       /* Let repl be r1 r2 ... rn. All these are already on the output queue.
+       /* Possibilities in order of most backup first are:
+       /* a)   pattern of form: p1 .... pb r1 r2 .... rn pc ... pd
+       /*      i.e. <repl> completely in pattern.
+       /*      requires a backup of b+n instructions
+       /*      and a goto to state 0.
+       /* b)   pattern of form: p1 .... pb r1 r2 .... ri
+       /*      i.e. a prefix of <repl> ends a pattern.
+       /*      requires a backup of b+n instructions
+       /*      and a goto to state 0.
+       /* c)   pattern of form: ri ri+1 ... rn pc ... pd
+       /*      i.e. a suffix of <repl> starts a pattern.
+       /*      requires a backup of n-i+1 instructions and a goto to state 0.
+       */
+       int n = repl.m_len;
+       int first,i,j;
+       int s;
+       int mostbackups = 0;
+       if(n==0) {
+               fprint(ofile,"\t\tbackup(%d);\n", longestpattern-1);
+               return;
+       }
+       for(s=1;s<=higheststate;s++) {
+               /* only match complete patterns */
+               if(actions[s]==(struct action *)NULL)
+                       continue;
+               /* look for case a */
+               if(first=rightmatch(patterns[s],repl,1,n)) {
+                       UPDATEWORST(first-1+n);
+               }
+               /* look for case b */
+               for(i=n-1;i;i--) {
+                       if((first=rightmatch(patterns[s],repl,1,i)) &&
+                          (first+i-1==patterns[s].m_len)) {
+                               UPDATEWORST(first-1+n);
+                       }
+               }
+               /* look for case c */
+               for(i=2;i<=n;i++) {
+                       if((first=leftmatch(patterns[s],repl,i,n)) &&
+                          (first==1)) {
+                               UPDATEWORST(n-i+1);
+                       }
+               }
+       }
+       if(mostbackups)
+               fprint(ofile,"\t\tbackup(%d);\n",mostbackups);
+}
+
+findfail(state)
+       int state;
+{
+       /*
+       /* If pattern matching fails in 'state', how many outputs and how many
+       /* push backs are requires. If pattern is of the form p1 p2 .... pn
+       /* look for patterns of the form p2 p3 ... pn; then p3 p4 ... pn; etc.
+       /* The first such match of the form pi pi+1 ... pn requires an output
+       /* of p1 p2 ... pi-1 and a push back of pn pn-1 ... pi. 
+       */
+       int s,i,j;
+       struct state *p;
+       int istrans;
+       int n = patterns[state].m_len;
+       for(i=2;i<=n;i++) {
+               for(s=1;s<=higheststate;s++) {
+                       /* exclude those on transitions from this state */
+                       istrans = 0;
+                       for(p=states[state];p!=(struct state *)NULL;p=p->next)
+                               if(s==p->goto_state)
+                                       istrans++;
+                       if(istrans)
+                               continue;
+                       if((leftmatch(patterns[s],patterns[state],i,n)==1)&&
+                               patterns[s].m_len==(n-i+1)) {
+                               fprint(ofile,"\t{%d,%d,%d},",i-1,n-i+1,s);
+                               return;
+                       }
+               }
+       }
+       fprint(ofile,"\t{%d,0,0},",n);
+}
+
+PRIVATE int
+leftmatch(patt,repl,i,j)
+       struct mnems patt,repl;
+       int i,j;
+{
+       /*
+       /* Return the first complete match of the mnems <ri,ri+1,..,rj> of
+       /* 'repl' in the mnems of 'patt'.  Find the leftmost match.
+       /* Return 0 if fails.
+       */
+       int lenrij = j-i+1;
+       int lastpos = patt.m_len - lenrij + 1;
+       int k,n;
+       for(k=1;k<=lastpos;k++) {
+               for(n=1;n<=lenrij;n++) {
+                       if(patt.m_elems[(k+n-1)-1]->op_code != repl.m_elems[(i+n-1)-1]->op_code)
+                               break;
+               }
+               if(n>lenrij) {
+                       return(k);
+               }
+       }
+       return(0);
+}
+
+PRIVATE int
+rightmatch(patt,repl,i,j)
+       struct mnems patt,repl;
+       int i,j;
+{
+       /*
+       /* Return the first complete match of the mnems <ri,ri+1,..,rj> of
+       /* 'repl' in the mnems of 'patt'.  Find the rightmost match.
+       /* Return 0 if fails.
+       */
+       int lenrij = j-i+1;
+       int lastpos = patt.m_len - lenrij + 1;
+       int k,n;
+       for(k=lastpos;k>=1;k--) {
+               for(n=1;n<=lenrij;n++) {
+                       if(patt.m_elems[(k+n-1)-1]->op_code != repl.m_elems[(i+n-1)-1]->op_code)
+                               break;
+               }
+               if(n>lenrij) {
+                       return(k);
+               }
+       }
+       return(0);
+}
diff --git a/modules/src/em_opt/initlex.c b/modules/src/em_opt/initlex.c
new file mode 100644 (file)
index 0000000..ef05d20
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include <em_mnem.h>
+#include <em_flag.h>
+#include <em_spec.h>
+#include "parser.h"
+#define op_lab 255
+
+#include <idf_pkg.body>
+
+extern char em_flag[];
+extern char em_mnem[][4];
+
+initlex()
+{
+       register int i,j;
+       init_idf();
+       idinit("lab",op_lab,DEFILB);
+       for(i=sp_fmnem;i<=sp_lmnem;i++) {
+               j=i-sp_fmnem;
+               switch(em_flag[j] & EM_PAR) {
+               case PAR_NO:
+                       idinit(em_mnem[j],i,NOARG); break;
+               case PAR_C:
+               case PAR_D:
+               case PAR_F:
+               case PAR_L:
+               case PAR_N:
+               case PAR_O:
+               case PAR_R:
+               case PAR_S:
+               case PAR_Z:
+                       idinit(em_mnem[j],i,CST); break;
+               case PAR_W:
+                       idinit(em_mnem[j],i,CSTOPT); break;
+               case PAR_P:
+                       idinit(em_mnem[j],i,PNAM); break;
+               case PAR_B:
+                       idinit(em_mnem[j],i,LAB); break;
+               case PAR_G:
+                       idinit(em_mnem[j],i,EXT); break;
+               }
+       }
+}
+
+PRIVATE
+idinit(tag,opcode,argfmt)
+       char *tag;
+       int opcode;
+       int argfmt;
+{
+       struct idf *p;
+       p = str2idf(tag,0);
+       p->id_nextidf = ops;            /* chain into all ops */
+       ops = p;
+       p->id_used = 0;
+       p->id_startpatt = 0;
+       p->id_opcode  = opcode;
+       p->id_argfmt = argfmt;
+}
diff --git a/modules/src/em_opt/mkcalls.c b/modules/src/em_opt/mkcalls.c
new file mode 100644 (file)
index 0000000..63d5489
--- /dev/null
@@ -0,0 +1,433 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "nopt.h"
+
+mkcalls(p)
+       struct instr *p;
+{
+       switch(p->argtype) {
+       case lab_ptyp:
+               O_df_ilb(p->alab); break;
+       case none_ptyp:
+               switch(p->opcode) {
+               case op_aar:
+                       O_aar_narg(); break;
+               case op_adf:
+                       O_adf_narg(); break;
+               case op_adi:
+                       O_adi_narg(); break;
+               case op_ads:
+                       O_ads_narg(); break;
+               case op_adu:
+                       O_adu_narg(); break;
+               case op_and:
+                       O_and_narg(); break;
+               case op_ass:
+                       O_ass_narg(); break;
+               case op_bls:
+                       O_bls_narg(); break;
+               case op_cmf:
+                       O_cmf_narg(); break;
+               case op_cmi:
+                       O_cmi_narg(); break;
+               case op_cms:
+                       O_cms_narg(); break;
+               case op_cmu:
+                       O_cmu_narg(); break;
+               case op_com:
+                       O_com_narg(); break;
+               case op_csa:
+                       O_csa_narg(); break;
+               case op_csb:
+                       O_csb_narg(); break;
+               case op_dus:
+                       O_dus_narg(); break;
+               case op_dvf:
+                       O_dvf_narg(); break;
+               case op_dvi:
+                       O_dvi_narg(); break;
+               case op_dvu:
+                       O_dvu_narg(); break;
+               case op_exg:
+                       O_exg_narg(); break;
+               case op_fef:
+                       O_fef_narg(); break;
+               case op_fif:
+                       O_fif_narg(); break;
+               case op_inn:
+                       O_inn_narg(); break;
+               case op_ior:
+                       O_ior_narg(); break;
+               case op_lar:
+                       O_lar_narg(); break;
+               case op_los:
+                       O_los_narg(); break;
+               case op_mlf:
+                       O_mlf_narg(); break;
+               case op_mli:
+                       O_mli_narg(); break;
+               case op_mlu:
+                       O_mlu_narg(); break;
+               case op_ngf:
+                       O_ngf_narg(); break;
+               case op_ngi:
+                       O_ngi_narg(); break;
+               case op_rck:
+                       O_rck_narg(); break;
+               case op_rmi:
+                       O_rmi_narg(); break;
+               case op_rmu:
+                       O_rmu_narg(); break;
+               case op_rol:
+                       O_rol_narg(); break;
+               case op_ror:
+                       O_ror_narg(); break;
+               case op_sar:
+                       O_sar_narg(); break;
+               case op_sbf:
+                       O_sbf_narg(); break;
+               case op_sbi:
+                       O_sbi_narg(); break;
+               case op_sbs:
+                       O_sbs_narg(); break;
+               case op_sbu:
+                       O_sbu_narg(); break;
+               case op_set:
+                       O_set_narg(); break;
+               case op_sli:
+                       O_sli_narg(); break;
+               case op_slu:
+                       O_slu_narg(); break;
+               case op_sri:
+                       O_sri_narg(); break;
+               case op_sru:
+                       O_sru_narg(); break;
+               case op_sts:
+                       O_sts_narg(); break;
+               case op_xor:
+                       O_xor_narg(); break;
+               case op_zer:
+                       O_zer_narg(); break;
+               case op_zrf:
+                       O_zrf_narg(); break;
+               /* no arguments */
+               case op_cai:
+                       O_cai(); break;
+               case op_cff:
+                       O_cff(); break;
+               case op_cfi:
+                       O_cfi(); break;
+               case op_cfu:
+                       O_cfu(); break;
+               case op_cif:
+                       O_cif(); break;
+               case op_cii:
+                       O_cii(); break;
+               case op_ciu:
+                       O_ciu(); break;
+               case op_cmp:
+                       O_cmp(); break;
+               case op_cuf:
+                       O_cuf(); break;
+               case op_cui:
+                       O_cui(); break;
+               case op_cuu:
+                       O_cuu(); break;
+               case op_dch:
+                       O_dch(); break;
+               case op_dec:
+                       O_dec(); break;
+               case op_inc:
+                       O_inc(); break;
+               case op_lim:
+                       O_lim(); break;
+               case op_lni:
+                       O_lni(); break;
+               case op_lpb:
+                       O_lpb(); break;
+               case op_mon:
+                       O_mon(); break;
+               case op_nop:
+                       O_nop(); break;
+               case op_rtt:
+                       O_rtt(); break;
+               case op_sig:
+                       O_sig(); break;
+               case op_sim:
+                       O_sim(); break;
+               case op_teq:
+                       O_teq(); break;
+               case op_tge:
+                       O_tge(); break;
+               case op_tgt:
+                       O_tgt(); break;
+               case op_tle:
+                       O_tle(); break;
+               case op_tlt:
+                       O_tlt(); break;
+               case op_tne:
+                       O_tne(); break;
+               case op_trp:
+                       O_trp(); break;
+               default:
+                       fatal("Illegal mnemonic(%d)",p->opcode);
+               }
+               break;
+       case cst_ptyp: /* one integer constant argument */
+               switch(p->opcode) {
+               case op_aar:
+                       O_aar(p->acst); break;
+               case op_adf:
+                       O_adf(p->acst); break;
+               case op_adi:
+                       O_adi(p->acst); break;
+               case op_adp:
+                       O_adp(p->acst); break;
+               case op_ads:
+                       O_ads(p->acst); break;
+               case op_adu:
+                       O_adu(p->acst); break;
+               case op_and:
+                       O_and(p->acst); break;
+               case op_asp:
+                       O_asp(p->acst); break;
+               case op_ass:
+                       O_ass(p->acst); break;
+               case op_blm:
+                       O_blm(p->acst); break;
+               case op_bls:
+                       O_bls(p->acst); break;
+               case op_cmf:
+                       O_cmf(p->acst); break;
+               case op_cmi:
+                       O_cmi(p->acst); break;
+               case op_cms:
+                       O_cms(p->acst); break;
+               case op_cmu:
+                       O_cmu(p->acst); break;
+               case op_com:
+                       O_com(p->acst); break;
+               case op_csa:
+                       O_csa(p->acst); break;
+               case op_csb:
+                       O_csb(p->acst); break;
+               case op_del:
+                       O_del(p->acst); break;
+               case op_dup:
+                       O_dup(p->acst); break;
+               case op_dus:
+                       O_dus(p->acst); break;
+               case op_dvf:
+                       O_dvf(p->acst); break;
+               case op_dvi:
+                       O_dvi(p->acst); break;
+               case op_dvu:
+                       O_dvu(p->acst); break;
+               case op_exg:
+                       O_exg(p->acst); break;
+               case op_fef:
+                       O_fef(p->acst); break;
+               case op_fif:
+                       O_fif(p->acst); break;
+               case op_inl:
+                       O_inl(p->acst); break;
+               case op_inn:
+                       O_inn(p->acst); break;
+               case op_ior:
+                       O_ior(p->acst); break;
+               case op_lal:
+                       O_lal(p->acst); break;
+               case op_lar:
+                       O_lar(p->acst); break;
+               case op_ldc:
+                       O_ldc(p->acst); break;
+               case op_ldf:
+                       O_ldf(p->acst); break;
+               case op_ldl:
+                       O_ldl(p->acst); break;
+               case op_lfr:
+                       O_lfr(p->acst); break;
+               case op_lil:
+                       O_lil(p->acst); break;
+               case op_lin:
+                       O_lin(p->acst); break;
+               case op_loc:
+                       O_loc(p->acst); break;
+               case op_lof:
+                       O_lof(p->acst); break;
+               case op_loi:
+                       O_loi(p->acst); break;
+               case op_lol:
+                       O_lol(p->acst); break;
+               case op_lor:
+                       O_lor(p->acst); break;
+               case op_los:
+                       O_los(p->acst); break;
+               case op_lxa:
+                       O_lxa(p->acst); break;
+               case op_lxl:
+                       O_lxl(p->acst); break;
+               case op_mlf:
+                       O_mlf(p->acst); break;
+               case op_mli:
+                       O_mli(p->acst); break;
+               case op_mlu:
+                       O_mlu(p->acst); break;
+               case op_ngf:
+                       O_ngf(p->acst); break;
+               case op_ngi:
+                       O_ngi(p->acst); break;
+               case op_rck:
+                       O_rck(p->acst); break;
+               case op_ret:
+                       O_ret(p->acst); break;
+               case op_rmi:
+                       O_rmi(p->acst); break;
+               case op_rmu:
+                       O_rmu(p->acst); break;
+               case op_rol:
+                       O_rol(p->acst); break;
+               case op_ror:
+                       O_ror(p->acst); break;
+               case op_sar:
+                       O_sar(p->acst); break;
+               case op_sbf:
+                       O_sbf(p->acst); break;
+               case op_sbi:
+                       O_sbi(p->acst); break;
+               case op_sbs:
+                       O_sbs(p->acst); break;
+               case op_sbu:
+                       O_sbu(p->acst); break;
+               case op_sdf:
+                       O_sdf(p->acst); break;
+               case op_sdl:
+                       O_sdl(p->acst); break;
+               case op_set:
+                       O_set(p->acst); break;
+               case op_sil:
+                       O_sil(p->acst); break;
+               case op_sli:
+                       O_sli(p->acst); break;
+               case op_slu:
+                       O_slu(p->acst); break;
+               case op_sri:
+                       O_sri(p->acst); break;
+               case op_sru:
+                       O_sru(p->acst); break;
+               case op_stf:
+                       O_stf(p->acst); break;
+               case op_sti:
+                       O_sti(p->acst); break;
+               case op_stl:
+                       O_stl(p->acst); break;
+               case op_str:
+                       O_str(p->acst); break;
+               case op_sts:
+                       O_sts(p->acst); break;
+               case op_xor:
+                       O_xor(p->acst); break;
+               case op_zer:
+                       O_zer(p->acst); break;
+               case op_zrf:
+                       O_zrf(p->acst); break;
+               case op_zrl:
+                       O_zrl(p->acst); break;
+               case op_beq:
+                       O_beq((label)p->acst); break;
+               case op_bge:
+                       O_bge((label)p->acst); break;
+               case op_bgt:
+                       O_bgt((label)p->acst); break;
+               case op_ble:
+                       O_ble((label)p->acst); break;
+               case op_blt:
+                       O_blt((label)p->acst); break;
+               case op_bne:
+                       O_bne((label)p->acst); break;
+               case op_bra:
+                       O_bra((label)p->acst); break;
+               case op_zeq:
+                       O_zeq((label)p->acst); break;
+               case op_zge:
+                       O_zge((label)p->acst); break;
+               case op_zgt:
+                       O_zgt((label)p->acst); break;
+               case op_zle:
+                       O_zle((label)p->acst); break;
+               case op_zlt:
+                       O_zlt((label)p->acst); break;
+               case op_zne:
+                       O_zne((label)p->acst); break;
+               default:
+                       fatal("Illegal mnemonic(%d)",p->opcode);
+               }
+               break;
+       case pro_ptyp: /* A procedure name argument */
+               switch(p->opcode) {
+               case op_cal:
+                       O_cal(p->apnam); break;
+               case op_lpi:
+                       O_lpi(p->apnam); break;
+               default:
+                       fatal("Illegal mnemonic(%d)",p->opcode);
+               }
+               break;
+       case nof_ptyp: /* a "g" argument */
+               switch(p->opcode) {
+               case op_dee:
+                       O_dee_dlb(p->adlb, p->anoff); break;
+               case op_fil:
+                       O_fil_dlb(p->adlb, p->anoff); break;
+               case op_gto:
+                       O_gto_dlb(p->adlb, p->anoff); break;
+               case op_ine:
+                       O_ine_dlb(p->adlb, p->anoff); break;
+               case op_lae:
+                       O_lae_dlb(p->adlb, p->anoff); break;
+               case op_lde:
+                       O_lde_dlb(p->adlb, p->anoff); break;
+               case op_loe:
+                       O_loe_dlb(p->adlb, p->anoff); break;
+               case op_sde:
+                       O_sde_dlb(p->adlb, p->anoff); break;
+               case op_ste:
+                       O_ste_dlb(p->adlb, p->anoff); break;
+               case op_zre:
+                       O_zre_dlb(p->adlb, p->anoff); break;
+               default:
+                       fatal("Illegal mnemonic(%d)",p->opcode);
+               }
+               break;
+       case sof_ptyp:
+               switch(p->opcode) {
+               case op_dee:
+                       O_dee_dnam(p->adnam, p->asoff); break;
+               case op_fil:
+                       O_fil_dnam(p->adnam, p->asoff); break;
+               case op_gto:
+                       O_gto_dnam(p->adnam, p->asoff); break;
+               case op_ine:
+                       O_ine_dnam(p->adnam, p->asoff); break;
+               case op_lae:
+                       O_lae_dnam(p->adnam, p->asoff); break;
+               case op_lde:
+                       O_lde_dnam(p->adnam, p->asoff); break;
+               case op_loe:
+                       O_loe_dnam(p->adnam, p->asoff); break;
+               case op_sde:
+                       O_sde_dnam(p->adnam, p->asoff); break;
+               case op_ste:
+                       O_ste_dnam(p->adnam, p->asoff); break;
+               case op_zre:
+                       O_zre_dnam(p->adnam, p->asoff); break;
+               default:
+                       fatal("Illegal mnemonic(%d)",p->opcode);
+               }
+               break;
+       default:
+               fatal("Illegal argtype(%d)",p->argtype);
+       }
+}
diff --git a/modules/src/em_opt/nopt.c b/modules/src/em_opt/nopt.c
new file mode 100644 (file)
index 0000000..e087e26
--- /dev/null
@@ -0,0 +1,506 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "nopt.h"
+#define MAXPATTERN     15
+#define MAXBACKUP      50
+#define MAXOUTPUT      200
+#define MAXFREEI       200
+#define MAXSTRING      1000
+
+#define GETINSTR() (nextifree>freeiqueue)?*(--nextifree):\
+       ((struct instr *)Malloc(sizeof(struct instr)))
+
+extern char em_mnem[][4];
+
+struct instr **patternqueue, **nextpatt;
+struct instr **backupqueue, **nextbackup, **lastbackup;
+struct instr **outputqueue, **nextoutput, **lastoutput;
+struct instr **freeiqueue,  **nextifree, **lastifree;
+char *strqueue, *nextstr, *laststr;
+
+int noutput;   /* number of instructions in output queue */
+int WSIZE;     /* wordlength */
+int PSIZE;     /* pointer length */
+
+#ifdef STATS
+int sflag = 1;                 /* pattern statistics output */
+#endif
+#ifdef COLLECT
+int cflag = 0;                 /* internal statistics output */
+#define UPDATEMAX(oldmax,n) if(cflag&&n>oldmax) oldmax=n
+int numwrites = 0;
+int numnextems = 0;
+int numpushs = 0;
+int numbackups = 0;
+int numflushes = 0;
+int numfrees = 0;
+int numdefaults = 0;
+int highestbackup = 0, totalbackup = 0;
+int highestoutput = 0, totaloutput = 0;
+int highestfreei = 0, totalfreei = 0;
+int higheststr = 0, totalstr = 0;
+#endif
+
+C_init(wsize,psize)
+       arith wsize, psize;
+{
+       allocmem();
+       O_init(wsize,psize);
+       WSIZE = wsize;
+       PSIZE = psize;
+}
+
+C_open(fname)
+       char *fname;
+{
+       return(O_open(fname));
+}
+
+C_magic()
+{
+       O_magic();
+}
+
+C_close()
+{
+#ifdef COLLECT
+       if(cflag)
+               outputstats();
+#endif
+       O_close();
+}
+
+PRIVATE
+allocmem()
+{
+       /* Allocate memory for queues on heap */
+       nextpatt = patternqueue =
+               (struct instr **)Malloc(MAXPATTERN*sizeof(struct instr *));
+       nextbackup = backupqueue =
+               (struct instr **)Malloc(MAXBACKUP*sizeof(struct instr *));
+       lastbackup = backupqueue + MAXBACKUP - 1;
+       nextoutput = outputqueue =
+               (struct instr **)Malloc(MAXOUTPUT*sizeof(struct instr *));
+       lastoutput = outputqueue + MAXOUTPUT - 1;
+       noutput = 0;
+       nextifree = freeiqueue =
+               (struct instr **)Malloc(MAXFREEI*sizeof(struct instr *));
+       lastifree = freeiqueue + MAXFREEI - 1;
+       nextstr = strqueue =
+               (char *)Malloc(MAXSTRING*sizeof(char));
+       laststr = strqueue + MAXSTRING - 1;
+}
+
+#ifdef COLLECT
+PRIVATE
+outputstats()
+{
+       int i;
+       fprint(STDERR,"Total of %d instructions read, %d written\n",numreads,numwrites);
+       fprint(STDERR,"Total of %d calls to nextem\n",numnextems);
+       fprint(STDERR,"Total of %d calls to flush\n",numflushes);
+       fprint(STDERR,"Total of %d calls to myfree\n",numfrees);
+       fprint(STDERR,"Total of %d instructions pushed back\n",numpushs-numbackups);
+       fprint(STDERR,"Total of %d instructions backed up\n",numbackups);
+       fprint(STDERR,"Total of %d calls to dodefault\n",numdefaults);
+       fprint(STDERR,"Max of highestbackup\t%d\t(%d)\t",highestbackup,MAXBACKUP);
+       printav(totalbackup);
+       fprint(STDERR,"Max of highestoutput\t%d\t(%d)\t",highestoutput,MAXOUTPUT);
+       printav(totaloutput);
+       fprint(STDERR,"Max of highestfreei\t%d\t(%d)\t",highestfreei,MAXFREEI);
+       printav(totalfreei);
+       fprint(STDERR,"Max of higheststr\t%d\t(%d)\t",higheststr,MAXSTRING);
+       printav(totalstr);
+}
+
+PRIVATE
+printav(n)
+       int n;
+{
+       fprint(STDERR,"Av.\t%d.%d\n",n/numflushes,(n*10)%numflushes);
+}
+#endif
+
+myfree(p)
+       struct instr *p;
+{
+#ifdef DEBUG
+       fprint(STDERR,"about to free ");
+       prtinst(p);
+       fprint(STDERR,"\n");
+#endif
+#ifdef COLLECT
+       if(cflag)
+               numfrees++;
+#endif
+       if(nextifree > lastifree) {
+#ifdef DEBUG
+               fprint(STDERR,"Warning: Overflow of freeiqueue-free arg ignored\n");
+               printstate("Freea overflow");
+#endif
+               return;
+       }
+       *nextifree++ = p;
+#ifdef COLLECT
+       UPDATEMAX(highestfreei,nextifree-freeiqueue);
+#endif
+}
+
+nfree(n)
+{
+       while(n--)
+               myfree(*--nextpatt);
+}
+
+PRIVATE char *
+freestr(s)
+       char *s;
+{
+       char *res = nextstr;
+       while(*nextstr++ = *s++);
+       if(nextstr > laststr) {
+               fprint(STDERR,"string space overflowed!\n");
+               sys_stop(S_EXIT);
+       }
+#ifdef COLLECT
+       UPDATEMAX(higheststr,nextstr-strqueue);
+#endif
+       return(res);
+}
+
+nextem()
+{
+       /*
+       /* Return the next instruction from backup queue else 0.
+       */
+#ifdef COLLECT
+       if(cflag)
+               numnextems++;
+#endif
+       if(nextbackup>backupqueue)
+               return((*nextpatt++ = *(--nextbackup))->opcode);
+       return(0);
+}
+
+flush()
+{
+       /*
+       /* Output all instructions waiting in the output queue and free their
+       /* storage including the saved strings.
+       */
+       struct instr **p;
+#ifdef DEBUG
+       printstate("Flush");
+#endif
+#ifdef COLLECT
+       if(cflag) {
+               numflushes++;
+               totaloutput += nextoutput-outputqueue;
+               totalbackup += nextbackup-backupqueue;
+               totalfreei += nextifree-freeiqueue;
+               totalstr += nextstr-strqueue;
+       }
+#endif
+       if(noutput) {
+               for(p=outputqueue;p<nextoutput;p++) {
+#ifdef COLLECT
+                       if(cflag)
+                               numwrites++;
+#endif
+                       mkcalls(*p);
+                       myfree(*p);
+               }
+               nextoutput=outputqueue;
+               if(nextbackup==backupqueue)
+                       nextstr = strqueue;
+               noutput = 0;
+       }
+}
+
+outop(opcode)
+       int opcode;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = none_ptyp;
+       output(p);
+}
+
+inop(opcode)
+       int opcode;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = none_ptyp;
+       *nextpatt++ = p;
+}
+
+outcst(opcode,cst)
+       int opcode,cst;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = cst_ptyp;
+       p->acst = cst;
+       output(p);
+}
+
+incst(opcode,cst)
+       int opcode,cst;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = cst_ptyp;
+       p->acst = cst;
+       *nextpatt++ = p;
+}
+
+outlab(opcode,lab)
+       int opcode,lab;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = cst_ptyp;
+       p->acst = lab;
+       output(p);
+}
+
+inlab(opcode,lab)
+       int opcode,lab;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = cst_ptyp;
+       p->acst = lab;
+       *nextpatt++ = p;
+}
+
+outpnam(opcode,pnam)
+       int opcode;
+       char *pnam;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = pro_ptyp;
+       p->apnam = pnam;
+       output(p);
+}
+
+inpnam(opcode,pnam)
+       int opcode;
+       char *pnam;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = pro_ptyp;
+       p->apnam = freestr(pnam);
+       *nextpatt++ = p;
+}
+
+outdefilb(opcode,deflb)
+       int opcode;
+       label deflb;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = lab_ptyp;
+       p->alab = deflb;
+       output(p);
+}
+
+indefilb(opcode,deflb)
+       int opcode;
+       label deflb;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = lab_ptyp;
+       p->alab = deflb;
+       *nextpatt++ = p;
+}
+
+outext(opcode,arg,soff)
+       int opcode;
+       struct instr *arg;
+       int soff;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       switch(p->argtype = arg->argtype) {
+       case cst_ptyp:
+               p->acst = soff;
+               break;
+       case sof_ptyp:
+               p->adnam = arg->adnam;
+               p->asoff = soff;
+               break;
+       case nof_ptyp:
+               p->adlb = arg->adlb;
+               p->anoff = soff;
+               break;
+       default:
+               fatal("Unexpected type %d in outext",arg->argtype);
+       }
+       output(p);
+}
+
+indnam(opcode,name,off)
+       int opcode;
+       char *name;
+       int off;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = sof_ptyp;
+       p->adnam = freestr(name);
+       p->asoff = off;
+       *nextpatt++ = p;
+}
+
+indlb(opcode,lab,off)
+       int opcode;
+       label lab;
+       int off;
+{
+       register struct instr *p = GETINSTR();
+       p->opcode = opcode;
+       p->argtype = nof_ptyp;
+       p->adlb = lab;
+       p->anoff = off;
+       *nextpatt++ = p;
+}
+
+output(p)
+       struct instr *p;
+{
+       /* Put the instruction p on the output queue */
+       if(nextoutput > lastoutput) {
+#ifdef DEBUG
+               fprint(STDERR,"Overflow of outputqueue - output flushed\n");
+               printstate("Output overflow");
+#endif
+               flush();
+       }
+       noutput++;
+       *nextoutput++ = p;
+#ifdef COLLECT
+       UPDATEMAX(highestoutput,nextoutput-outputqueue);
+#endif
+}
+
+pushback(p)
+       struct instr *p;
+{
+       /* push instr. p onto backupqueue */
+       if(nextbackup > lastbackup) {
+#ifdef DEBUG
+               fprint(STDERR,"Warning: Overflow of backupqueue-backup ignored\n");
+               printstate("Backup overflow");
+#endif
+               return;
+       }
+       *nextbackup++ = p;
+#ifdef COLLECT
+       UPDATEMAX(highestbackup,nextbackup-backupqueue);
+       numpushs++;
+#endif
+}
+
+backup(n)
+       int n;
+{
+       /* copy (up to) n instructions from output to backup queues */
+       while(n-- && nextoutput>outputqueue) {
+#ifdef COLLECT
+               if(cflag)
+                       numbackups++;
+#endif
+               pushback(*(--nextoutput));
+               noutput--;
+       }
+}
+
+dodefault(numout, numcopy)
+       int numout, numcopy;
+{
+       register struct instr **p,**q;
+       q = (p = patternqueue) + numout;
+       while(numcopy--) {
+               if(numout) {
+                       numout--;
+                       output(*p);
+               }
+               *p++ = *q++;
+       }
+       nextpatt = p;
+       while(numout--) output(*p++);
+#ifdef COLLECT
+       if(cflag)
+               numdefaults++;
+#endif
+}
+
+#ifdef DEBUG
+PRIVATE
+printstate(mess)
+       char *mess;
+{
+       struct instr **p;
+       fprint(STDERR,"%s - state: ",mess);
+       p = outputqueue;
+       while(p<nextoutput)
+               prtinst(*p++);
+       fprint(STDERR," |==| ");
+       p = patternqueue;
+       while(p<nextpatt)
+               prtinst(*p++);
+       fprint(STDERR," |==| ");
+       p = backupqueue;
+       while(p<nextbackup)
+               prtinst(*p++);
+       fprint(STDERR,"\n");
+}
+
+PRIVATE
+prtinst(p)
+       struct instr *p;
+{
+       switch(p->opcode) {
+       default:
+               fprint(STDERR,"%s",em_mnem[p->opcode-sp_fmnem]);
+               break;
+       case OTHER:
+               fprint(STDERR,"OTHER");
+               break;
+       case op_lab:
+               break;
+       }
+       switch(p->argtype) {
+       case none_ptyp:
+               fprint(STDERR," ");
+               break;
+       case cst_ptyp:
+               fprint(STDERR," %d ",p->acst);
+               break;
+       case lab_ptyp:
+               fprint(STDERR,"%d: ",p->alab);
+               break;
+       case nof_ptyp:
+               fprint(STDERR," .%d+%d ",p->adlb,p->asoff);
+               break;
+       case sof_ptyp:
+               fprint(STDERR," %s+%d ",p->adnam,p->asoff);
+               break;
+       case ilb_ptyp:
+               fprint(STDERR," *%d ",p->alab);
+               break;
+       case pro_ptyp:
+               fprint(STDERR," $%s ",p->apnam);
+               break;
+       default:
+               fatal(" prtinst - Unregognized arg %d ",p->argtype);
+       }
+}
+#endif
diff --git a/modules/src/em_opt/nopt.h b/modules/src/em_opt/nopt.h
new file mode 100644 (file)
index 0000000..5702b92
--- /dev/null
@@ -0,0 +1,65 @@
+/* $Header$ */
+#include <em_spec.h>
+#include <em_mnem.h>
+#include <em_pseu.h>
+#include <em_flag.h>
+#include <em_ptyp.h>
+#include <em_mes.h>
+#include <alloc.h>
+#include <em.h>
+#include <em_comp.h>
+#include <system.h>
+#include <idf_pkg.spec>
+
+#define NULL 0
+#define FLUSHDFA()     if(state) { inop(OTHER); dfa(OTHER); } \
+                       else if(noutput) flush();
+
+#define op_lab 255
+#define OTHER  254
+#define none_ptyp 0
+
+
+struct e_instr *EM_getinstr();
+
+struct instr {
+       int opcode;
+       int argtype;
+       union {
+               arith cst;
+               label lab;
+               char  *pnam;
+               struct {
+                       label dlb;
+                       arith noff;
+               } ndlb;
+               struct {
+                       char  *dnam;
+                       arith soff;
+               } sdlb;
+       } val;
+#define acst val.cst
+#define alab val.lab
+#define apnam val.pnam
+#define adlb val.ndlb.dlb
+#define anoff val.ndlb.noff
+#define adnam val.sdlb.dnam
+#define asoff val.sdlb.soff
+};
+
+extern struct instr **patternqueue, **nextpatt;
+extern int state;
+extern int noutput;    /* number of instructions in output queue */
+extern int WSIZE;      /* wordlength */
+extern int PSIZE;      /* pointer length */
+#ifdef DEBUG
+extern int dflag;                      /* debugging output */
+#endif
+#ifdef STATS
+extern int sflag;                      /* statistics output */
+#endif
+
+#define CST(p)         (p->acst)
+#define PNAM(p)                (p->apnam)
+#define LAB(p)         (p->alab)
+#define DEFILB(p)      (p->alab)
diff --git a/modules/src/em_opt/outcalls.c b/modules/src/em_opt/outcalls.c
new file mode 100644 (file)
index 0000000..0c6727e
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "parser.h"
+
+outputincalls()
+{
+       struct idf *op;
+       int opcode;
+       char *s;
+       if(!sys_open("incalls.c",OP_WRITE,&ofile)) {
+               fprint(STDERR,"Fatal Error: cannot open output file incalls.c\n");
+               sys_stop(S_EXIT);
+       }
+       fprint(ofile,"#include \"nopt.h\"\n\n");
+       for(op=ops;op!=(struct idf *)NULL;op=op->id_nextidf) {
+               opcode = op->id_opcode;
+               s = op->id_text;
+               switch(op->id_argfmt) {
+               case NOARG:
+                       fprint(ofile,"\nC_%s() {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tinop(op_%s);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s();\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       break;
+               case CSTOPT:
+                       fprint(ofile,"\nC_%s_narg() {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tinop(op_%s);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s_narg();\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       /* fall thru */
+               case CST:
+                       fprint(ofile,"\nC_%s(n) int n; {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tincst(op_%s,n);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s(n);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       break;
+               case DEFILB:
+                       fprint(ofile,"\nC_df_ilb(l) label l; {\n");
+                       if(op->id_used) {
+                               fprint(ofile,"\tindefilb(op_%s,l);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_df_ilb(l);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       break;
+               case PNAM:
+                       fprint(ofile,"\nC_%s(s) char *s; {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tinpnam(op_%s,s);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s(s);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       break;
+               case LAB:
+                       fprint(ofile,"\nC_%s(l) label l; {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tinlab(op_%s,l);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s(l);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       break;
+               case EXT:
+                       fprint(ofile,"\nC_%s(n) int n; {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tincst(op_%s,n);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s(n);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       fprint(ofile,"\nC_%s_dnam(s,n) char *s; int n; {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tindnam(op_%s,s,n);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s_dnam(s,n);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       fprint(ofile,"\nC_%s_dlb(l,n) label l; int n; {\n",s);
+                       if(op->id_used) {
+                               fprint(ofile,"\tindlb(op_%s,l,n);\n",s);
+                               fprint(ofile,"\tdfa(op_%s);\n",s);
+                       }
+                       else {
+                               fprint(ofile,"\tFLUSHDFA();\n");
+                               fprint(ofile,"\tO_%s_dlb(l,n);\n",s);
+                       }
+                       fprint(ofile,"}\n",s);
+                       break;
+               }
+       }
+}
diff --git a/modules/src/em_opt/outputdfa.c b/modules/src/em_opt/outputdfa.c
new file mode 100644 (file)
index 0000000..e8eff2a
--- /dev/null
@@ -0,0 +1,392 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "parser.h"
+#include "Lpars.h"
+
+File *ofile;
+
+outputnopt()
+{
+       if(!sys_open("dfa.c",OP_WRITE,&ofile)) {
+               fprint(STDERR,"Couldn't open dfa.c for output\n");
+               sys_stop(S_EXIT);
+       }
+       outputheaders();
+       outputtables();
+       outputdfa();
+       outputdodefault();
+       outputdotrans();
+       outputincalls();
+}
+
+PRIVATE
+outputheaders()
+{
+       fprint(ofile,"#include \"nopt.h\"\n");
+       fprint(ofile,"\n");
+}
+
+PRIVATE
+outputtables()
+{
+       int s;
+       fprint(ofile,"struct defact {\n");
+       fprint(ofile,"\tint numoutput;\n");
+       fprint(ofile,"\tint numcopy;\n");
+       fprint(ofile,"\tint nextstate;\n");
+       fprint(ofile,"} defaultactions[] = {\n");
+       for(s=0;s<=higheststate;s++) {
+               findfail(s);
+               if(s%4==3)
+                       fprint(ofile,"\n");
+       }
+       fprint(ofile,"};\n");
+       fprint(ofile,"\n");
+}
+
+PRIVATE
+outputdfa()
+{
+       int s;
+       struct idf *op;
+       struct state *p;
+       fprint(ofile,"int state = 0;\n");
+       fprint(ofile,"\n");
+       fprint(ofile,"dfa(last) int last; {\n");
+       fprint(ofile,"\twhile(last) {\n");
+       fprint(ofile,"\t\tswitch(last) {\n");
+       for(op=ops;op!=(struct idf *)NULL;op=op->id_nextidf) {
+               if(!op->id_used)
+                       continue;
+               fprint(ofile,"\t\tcase op_%s:\n",op->id_text);
+               fprint(ofile,"\t\t\tswitch(state) {\n");
+               if(!op->id_startpatt) {
+                               fprint(ofile,"\t\t\tcase 0: ");
+                               fprint(ofile,"output(*--nextpatt); ");
+                               fprint(ofile,"break;\n");
+               }
+               for(s=0;s<=higheststate;s++)
+                       for(p=states[s];p!=(struct state *)NULL;p=p->next) {
+                               if(p->op==op) {
+                                       fprint(ofile,"\t\t\tcase %d: ",s);
+                                       if(actions[p->goto_state]==(struct action *)NULL)
+                                               fprint(ofile,"state = %d; ",p->goto_state);
+                                       else fprint(ofile,"dotrans(%d); ",p->goto_state);
+                                       fprint(ofile,"break;\n");
+                               }
+                       }
+               fprint(ofile,"\t\t\tdefault: defaultaction(); break;\n");
+               fprint(ofile,"\t\t\t}\n");
+               fprint(ofile,"\t\t\tbreak;\n");
+       }
+       fprint(ofile,"\t\tdefault:\n");
+       fprint(ofile,"\t\t\tif(state) defaultaction();\n");
+       fprint(ofile,"\t\t\telse {\n");
+       fprint(ofile,"\t\t\t\tflush();\n");
+       fprint(ofile,"\t\t\t\tmkcalls(*--nextpatt);\n");
+       fprint(ofile,"\t\t\t\tmyfree(*nextpatt);\n");
+       fprint(ofile,"\t\t\t}\n");
+       fprint(ofile,"\t\t\tbreak;\n");
+       fprint(ofile,"\t\tcase OTHER:\n");
+       fprint(ofile,"\t\t\tif(state) defaultaction();\n");
+       fprint(ofile,"\t\t\telse {\n");
+       fprint(ofile,"\t\t\t\tflush();\n");
+       fprint(ofile,"\t\t\t\tmyfree(*--nextpatt);\n");
+       fprint(ofile,"\t\t\t}\n");
+       fprint(ofile,"\t\t\tbreak;\n");
+       fprint(ofile,"\t\t}\n");
+       fprint(ofile,"\tlast = nextem();\n");
+       fprint(ofile,"\t}\n");
+       fprint(ofile,"}\n");
+}
+
+PRIVATE
+outputmnems(l,state)
+       struct mnems l;
+       int state;
+{
+       int i;
+       for(i=1;i<=l.m_len;i++) 
+               fprint(ofile,"%s ",l.m_elems[i-1]->op_code->id_text);
+}
+
+PRIVATE
+outputdotrans()
+{
+       int s;
+       struct state *p;
+       struct action *a;
+       int seennontested;
+       if(!sys_open("trans.c",OP_WRITE,&ofile)) {
+               fprint(STDERR,"Fatal Error: cannot open output file trans.c\n");
+               sys_stop(S_EXIT);
+       }
+       fprint(ofile,"#include \"nopt.h\"\n\n");
+       fprint(ofile,"\ndotrans(s) int s; {\n");
+       fprint(ofile,"\tswitch(state=s) {\n");
+       fprint(ofile,"\tdefault: return;\n");
+       for(s=0;s<=higheststate;s++)
+               if(actions[s]!=(struct action *)NULL) {
+                       fprint(ofile,"\tcase %d: /*",s);
+                       outputmnems(patterns[s],s);
+                       fprint(ofile," */\n");
+                       seennontested=0;
+                       for(a=actions[s];a!=(struct action *)NULL;a=a->next) {
+                               if(a->test!=(struct exp_node *)NULL) {
+                                       fprint(ofile,"\t\tif(");
+                                       outputexp(a->test,s);
+                                       /*
+                                       /*fprint(ofile,"dotest(%d)",a->linenum);
+                                       */
+                                       fprint(ofile,") {\n");
+                                       /*
+                                       /*fprint(ofile,"\t\t\tdoaction(%d);\n",a->linenum);
+                                       */
+                                       outputoneaction(s,a);
+                                       fprint(ofile,"\t\t\tnfree(%d);\n",patterns[s].m_len);
+                                       fprint(ofile,"\t\t\tstate=0;\n");
+                                       fprint(ofile,"\t\t\tbreak;\n");
+                                       fprint(ofile,"\t\t}\n");
+                               }
+                               else {
+                                       if(seennontested) {
+                                               fprint(STDERR,"parser: more than one untested action on state %d\n",s);
+                                               nerrors++;
+                                       }
+                                       seennontested++;
+                                       /*
+                                       /*fprint(ofile,"\t\t\tdoaction(%d);\n",a->linenum);
+                                       */
+                                       outputoneaction(s,a);
+                                       fprint(ofile,"\t\tnfree(%d);\n",patterns[s].m_len);
+                                       fprint(ofile,"\t\tstate=0;\n");
+                                       fprint(ofile,"\t\tbreak;\n");
+                               }
+                       }
+                       fprint(ofile,"\t\tbreak;\n");
+               }
+       fprint(ofile,"\t}\n");
+       fprint(ofile,"}\n");
+       fprint(ofile,"\n");
+}
+
+PRIVATE
+outputdodefault()
+{
+       fprint(ofile,"\nstatic defaultaction() {\n");
+       fprint(ofile,"\tregister struct defact *p = &defaultactions[state];\n");
+       fprint(ofile,"\tpushback(*--nextpatt);\n");
+       fprint(ofile,"\tdodefault(p->numoutput,p->numcopy);\n");
+       fprint(ofile,"\tdotrans(p->nextstate);\n");
+       fprint(ofile,"}\n");
+}
+
+PRIVATE
+outputoneaction(s,a)
+       int s;
+       struct action *a;
+{
+       fprint(ofile,"\t\t/* ");
+       fprint(ofile," -> ");
+       outputmnems(a->replacement,s);
+       fprint(ofile," */\n");
+       outputrepl(s,patterns[s],a->replacement);
+       findworst(s,a->replacement);
+}
+
+PRIVATE
+outputrepl(state,patt,repl)
+       int state;
+       struct mnems patt,repl;
+{
+       /*
+       /* Contruct <repl>=r1 r2 ... rn and put on output queue.
+       */
+       int n = repl.m_len;
+       int m = patt.m_len;
+       int i,j,count;
+       for(i=1;i<=n;i++) {
+               struct mnem_elem *ri = repl.m_elems[i-1];
+               char *mnem = ri->op_code->id_text;
+               switch(ri->op_code->id_argfmt) {
+               case NOARG:
+                       fprint(ofile,"\t\toutop(op_%s);\n",mnem);
+                       break;
+               case CST:
+               case CSTOPT:
+                       fprint(ofile,"\t\toutcst(op_%s,",mnem);
+                       outputexp(ri->arg,state);
+                       fprint(ofile,");\n");
+                       break;
+               case LAB:
+                       fprint(ofile,"\t\toutlab(op_%s,",mnem);
+                       outputexp(ri->arg,state);
+                       fprint(ofile,");\n");
+                       break;
+               case DEFILB:
+                       fprint(ofile,"\t\toutdefilb(op_%s,",mnem);
+                       outputexp(ri->arg,state);
+                       fprint(ofile,");\n");
+                       break;
+               case PNAM:
+                       fprint(ofile,"\t\toutpnam(op_%s,",mnem);
+                       outputexp(ri->arg,state);
+                       fprint(ofile,");\n");
+                       break;
+               case EXT:
+                       fprint(ofile,"\t\toutext(op_%s,",mnem);
+                       outputexp(ri->arg,state);
+                       fprint(ofile,");\n");
+                       break;
+               }
+       }
+}
+
+PRIVATE
+outputexp(e,state)
+       struct exp_node *e;
+       int state;
+{
+       switch(e->node_type) {
+       case LOGAND:
+       case LOGOR:
+       case BITAND:
+       case BITOR:
+       case XOR:
+       case MINUS:
+       case PLUS:
+       case TIMES:
+       case DIV:
+       case MOD:
+       case EQ:
+       case NE:
+       case LT:
+       case LE:
+       case GT:
+       case GE:
+       case LSHIFT:
+       case RSHIFT:
+               fprint(ofile,"(");
+               outputexp(e->exp_left,state);
+               outputop(e->node_type);
+               outputexp(e->exp_right,state);
+               fprint(ofile,")");
+               break;
+       case NOT:
+       case COMP:
+       case UPLUS:
+       case UMINUS:
+               fprint(ofile,"(");
+               outputop(e->node_type);
+               outputexp(e->exp_left,state);
+               fprint(ofile,")");
+               break;
+       case DEFINED:
+               fprint(ofile,"(patternqueue[%d]->argtype!=none_ptyp)",e->leaf_val-1);
+               break;
+       case UNDEFINED:
+               fprint(ofile,"(patternqueue[%d]->argtype==none_ptyp)",e->leaf_val-1);
+               break;
+       case COMMA:
+               outext(e->exp_left);
+               fprint(ofile,","); outputexp(e->exp_right,state);
+               break;
+       case SAMESIGN:
+       case SFIT:
+       case UFIT:
+       case ROTATE:
+               outputop(e->node_type);
+               outputexp(e->exp_left,state);
+               fprint(ofile,",");
+               outputexp(e->exp_right,state);
+               fprint(ofile,")");
+               break;
+       case SAMEEXT:
+       case SAMENAM:
+               outputop(e->node_type);
+               outext(e->exp_left);
+               fprint(ofile,",");
+               outext(e->exp_right,state);
+               fprint(ofile,")");
+               break;
+       case PATARG:
+               switch(patterns[state].m_elems[e->leaf_val-1]->op_code->id_argfmt) {
+               case NOARG:
+                       fprint(STDERR,"error: mnem %d has no argument\n",e->leaf_val);
+                       nerrors++;
+                       break;
+               case CST:
+               case CSTOPT:
+                       fprint(ofile,"CST(patternqueue[%d])",e->leaf_val-1);
+                       break;
+               case LAB:
+                       fprint(ofile,"LAB(patternqueue[%d])",e->leaf_val-1);
+                       break;
+               case DEFILB:
+                       fprint(ofile,"DEFILB(patternqueue[%d])",e->leaf_val-1);
+                       break;
+               case PNAM:
+                       fprint(ofile,"PNAM(patternqueue[%d])",e->leaf_val-1);
+                       break;
+               case EXT:
+                       fprint(ofile,"offset(patternqueue[%d])",e->leaf_val-1);
+                       break;
+               }
+               break;
+       case PSIZE:
+               fprint(ofile,"PSIZE"); break;
+       case WSIZE:
+               fprint(ofile,"WSIZE"); break;
+       case INT:
+               fprint(ofile,"%d",e->leaf_val); break;
+       }
+}
+
+PRIVATE
+outext(e)
+       struct exp_node *e;
+{
+       if(e->node_type!=PATARG) {
+               fprint(STDERR,"Internal error in outext of parser\n");
+               nerrors++;
+       }
+       fprint(ofile,"patternqueue[%d]",e->leaf_val-1);
+}
+
+PRIVATE
+outputop(op)
+       int op;
+{
+       switch(op) {
+       case LOGAND:    fprint(ofile,"&&");     break;
+       case LOGOR:     fprint(ofile,"||");     break;
+       case BITAND:    fprint(ofile,"&");      break;
+       case BITOR:     fprint(ofile,"|");      break;
+       case XOR:       fprint(ofile,"^");      break;
+       case MINUS:     fprint(ofile,"-");      break;
+       case PLUS:      fprint(ofile,"+");      break;
+       case TIMES:     fprint(ofile,"*");      break;
+       case DIV:       fprint(ofile,"/");      break;
+       case MOD:       fprint(ofile,"%%");     break;
+       case EQ:        fprint(ofile,"==");     break;
+       case NE:        fprint(ofile,"!=");     break;
+       case LT:        fprint(ofile,"<");      break;
+       case LE:        fprint(ofile,"<=");     break;
+       case GT:        fprint(ofile,">");      break;
+       case GE:        fprint(ofile,">=");     break;
+       case LSHIFT:    fprint(ofile,"<<");     break;
+       case RSHIFT:    fprint(ofile,">>");     break;
+       case NOT:       fprint(ofile,"!");      break;
+       case COMP:      fprint(ofile,"~");      break;
+       case UPLUS:     fprint(ofile,"+");      break;
+       case UMINUS:    fprint(ofile,"-");      break;
+       case SAMESIGN:  fprint(ofile,"samesign(");      break;
+       case SFIT:      fprint(ofile,"sfit(");  break;
+       case UFIT:      fprint(ofile,"ufit(");  break;
+       case ROTATE:    fprint(ofile,"rotate(");        break;
+       case SAMEEXT:   fprint(ofile,"sameext(");       break;
+       case SAMENAM:   fprint(ofile,"samenam(");       break;
+       }
+}
diff --git a/modules/src/em_opt/parser.g b/modules/src/em_opt/parser.g
new file mode 100644 (file)
index 0000000..8573236
--- /dev/null
@@ -0,0 +1,496 @@
+/* $Header$ */
+/* Parser to read optimization patterns of the form:
+               op1 op2 ... test : action
+       or
+               op1 op2 ... : action
+   and build a program to recognize then */
+
+%token SFIT, UFIT, ROTATE, PSIZE, WSIZE, DEFINED, UNDEFINED, SAMESIGN;
+%token SAMEEXT, SAMENAM, OFFSET, LOGAND, LOGOR, BITAND, BITOR, XOR;
+%token MINUS, PLUS, TIMES, DIV, MOD, EQ, NE, LT, LE, GT, GE, NOT, COMP;
+%token LSHIFT, RSHIFT, COMMA, OPCODE, INT, UPLUS, UMINUS, PATARG;
+
+%start parser, input;
+
+{
+#include "parser.h"
+
+#define MAXPRIO 11
+
+struct state   *states[MAXSTATES];
+struct action  *actions[MAXSTATES];
+struct mnems   patterns[MAXSTATES];
+int higheststate = 0;                  /* Highest state yet allocated */
+struct idf *ops;                       /* Chained list of all ops */
+int longestpattern = 0;
+int nerrors = 0;
+
+static int lencurrpatt;
+static int lenthisrepl;
+static int currentstate;               /* Current state of dfa */
+}
+
+input  : /* empty */
+       | optimization input
+       ;
+
+optimization
+                       {
+                       int startline;
+                       struct exp_node *restrictions;
+                       struct exp_node *finaltest;
+                       struct mnem_list *repllist;
+                       }
+       :
+                       {
+                       startline=linenum; currentstate=0;
+                       lencurrpatt=0; lenthisrepl=0;
+                       }
+       patterns(&restrictions)
+                       { finaltest = (struct exp_node *)NULL; }
+       [
+               '?'
+               exp(1,&finaltest)
+       ]?
+       ':'
+       action(&repllist)
+                       {
+                       addaction(startline,currentstate,restrictions,
+                               finaltest,repllist);
+                       }
+       '\n'
+       ;
+
+patterns(struct exp_node **tests;)
+       { struct mnem_list *list;
+         struct exp_node *pair1, *pair2;
+         struct exp_node *onetest; int argtype; }
+       :
+               {
+               list = (struct mnem_list *)NULL;
+               *tests = (struct exp_node *)NULL;
+               }
+       [
+       OPCODE
+               {
+               if(++lencurrpatt>longestpattern)
+                       longestpattern=lencurrpatt;
+               list = addelem(list,opval, (struct exp_node *)NULL);
+               opval->id_used=1;
+               if(lencurrpatt==1)
+                       opval->id_startpatt=1;
+               currentstate=dotransition(currentstate,opval,list,lencurrpatt);
+               }
+       [
+               restriction(opval->id_argfmt,&onetest)
+                       {
+                       *tests = combinetests(*tests,onetest);
+                       }
+       ]?
+       ]+
+       ;
+
+restriction(int argtype; struct exp_node **test;)
+                       {
+                       struct exp_node *test1,*test2;
+                       int relop;
+                       int offsetop;
+                       }
+       :
+       [ %if(argtype==CSTOPT)
+               [ optrelop(&relop) exp(1,test)
+                       {
+                       *test = mknode(relop,mkleaf(PATARG,lencurrpatt),*test);
+                       *test = mknode(LOGAND,
+                               mkleaf(DEFINED,lencurrpatt),
+                               *test);
+                       }
+               | DEFINED
+                       {
+                       *test = mkleaf(DEFINED,lencurrpatt);
+                       }
+               | UNDEFINED
+                       {
+                       *test = mkleaf(UNDEFINED,lencurrpatt);
+                       }
+               ]
+       | %if(argtype==EXT)
+               patarg(&test1)
+                       {
+                       *test=mknode(SAMEEXT,
+                               mkleaf(PATARG,lencurrpatt),
+                               test1);
+                       }
+               [
+                       [ PLUS
+                               { offsetop = PLUS; }
+                       | MINUS
+                               { offsetop = MINUS; }
+                       ]
+                       exp(1,&test2)
+                               {
+                               test2 = mknode(offsetop, test1, test2);
+                               test2 = mknode(EQ, mkleaf(PATARG,lencurrpatt), test2);
+                               *test = combinetests(
+                                       mknode(SAMENAM,
+                                               mkleaf(PATARG,lencurrpatt),
+                                               test1),
+                                       test2);
+                               }
+               ]?
+       |
+               optrelop(&relop) exp(1,test)
+                       {
+                       *test = mknode(relop,mkleaf(PATARG,lencurrpatt),*test);
+                       }
+       ]
+       ;
+
+optrelop(int *op;)
+       :
+               {*op = EQ;}
+       [ EQ    {*op = EQ;}
+       | NE    {*op = NE;}
+       | LT    {*op = LT;}
+       | LE    {*op = LE;}
+       | GT    {*op = GT;}
+       | GE    {*op = GE;}
+       ]?
+       ;
+action(struct mnem_list **list;)
+                       {
+                       struct exp_node *test, *test2;
+                       struct idf *keepopval;
+                       int offsetop;
+                       }
+       :
+                       { *list = (struct mnem_list *)NULL; }
+       [
+       OPCODE
+                       {
+                       lenthisrepl++;
+                       test= (struct exp_node *)NULL;
+                       keepopval = opval;
+                       }
+               [ %if(keepopval->id_argfmt==EXT)
+               patarg(&test)
+                               {
+                               test2 = test;
+                               }
+                       [
+                               [ PLUS
+                                       { offsetop = PLUS; }
+                               | MINUS
+                                       { offsetop = MINUS; }
+                               ]
+                               exp(1,&test2)
+                                       {
+                                       test2 = mknode(offsetop,test,test2);
+                                       }
+
+                       ]?
+                               {
+                               test = mknode(COMMA,test,test2);
+                               }
+               | exp(1,&test)
+               ]?
+                               {
+                               *list = addelem(*list,keepopval,test);
+                               }
+       ]*
+       ;
+
+exp(int level; struct exp_node **result;)
+                       { struct exp_node *res1, *res2;
+                         int operator, intval; }
+               :
+               %if(level <= MAXPRIO)
+               exp(MAXPRIO+1,&res1)
+                       [ %while (priority(LLsymb) >= level)
+                         binop
+                               {
+                               operator=LLsymb;
+                               }
+                         exp(priority(operator)+1,&res2)
+                               {
+                               res1 = mknode(operator,res1,res2);
+                               }
+                       ]*
+                               {
+                               *result = res1;
+                               }
+               | '(' exp(1,result) ')'
+               | unaryop(&operator) exp(priority(operator)+1,&res1)
+                       {
+                       *result = mknode(operator,res1,(struct exp_node *)NULL);
+                       }
+               | SAMESIGN '(' exp(1,&res1) COMMA exp(1,&res2) ')'
+                       {
+                       *result = mknode(SAMESIGN,res1,res2);
+                       }
+               | SFIT '(' exp(1,&res1) COMMA exp(1,&res2) ')'
+                       {
+                       *result = mknode(SFIT,res1,res2);
+                       }
+               | UFIT '(' exp(1,&res1) COMMA exp(1,&res2) ')'
+                       {
+                       *result = mknode(UFIT,res1,res2);
+                       }
+               | ROTATE '(' exp(1,&res1) COMMA exp(1,&res2) ')'
+                       {
+                       *result = mknode(ROTATE,res1,res2);
+                       }
+               | SAMEEXT '(' patarg(&res1) COMMA patarg(&res2) ')'
+                       {
+                       *result = mknode(SAMEEXT,res1,res2);
+                       }
+               | SAMENAM '(' patarg(&res1) COMMA patarg(&res2) ')'
+                       {
+                       *result = mknode(SAMENAM,res1,res2);
+                       }
+               | OFFSET '(' patarg(&res1) ')'
+                       {
+                       *result = res1;
+                       }
+               | patarg(result)
+               | PSIZE
+                       {
+                       *result = mkleaf(PSIZE,0);
+                       }
+               | WSIZE
+                       {
+                       *result = mkleaf(WSIZE,0);
+                       }
+               | INT
+                       {
+                       *result = mkleaf(INT,lastintval);
+                       }
+               ;
+
+patarg(struct exp_node **result;)
+               { int intval; }
+       :  PATARG argno(&intval)
+               {
+               *result = mkleaf(PATARG,intval);
+               }
+       ;
+
+argno(int *val;)
+       : INT
+               {
+               *val = lastintval;
+               if(lastintval<0 || (lastintval>lencurrpatt)) {
+                       fprint(STDERR ,"Illegal $%d on line %d\n",
+                                       lastintval,linenum);
+                       nerrors++;
+               }
+               }
+       ;
+
+unaryop(int *operator;)
+       : PLUS  { *operator = UPLUS; }
+       | MINUS { *operator = UMINUS; }
+       | NOT   { *operator = NOT; }
+       | COMP  { *operator = COMP; }
+       ;
+
+binop  : LOGAND
+       | LOGOR
+       | BITAND
+       | BITOR
+       | XOR
+       | MINUS
+       | PLUS
+       | TIMES
+       | DIV
+       | MOD
+       | EQ
+       | NE
+       | LT
+       | LE
+       | GT
+       | GE
+       | LSHIFT
+       | RSHIFT
+       ;
+
+%lexical yylex;
+
+{
+addaction(startline, state, restrictions, finaltest, repllist)
+       int startline;
+       int state;
+       struct exp_node *restrictions, *finaltest;
+       struct mnem_list *repllist;
+{
+       struct action *p, *q;
+       p=(struct action *)Malloc(sizeof(struct action));
+       p->next = (struct action *)NULL;
+       p->linenum = startline;
+       p->test = combinetests(restrictions,finaltest);
+       p->replacement.m_len = lenthisrepl;
+       p->replacement.m_elems = constructlist(repllist,lenthisrepl);
+       /* chain new action to END of action chain */
+       if((q = actions[currentstate])==(struct action *)NULL)
+               actions[currentstate] = p;
+       else {
+               while(q->next != (struct action *)NULL)
+                       q = q->next;
+               q->next = p;
+       }
+}
+
+struct mnem_elem **
+constructlist(list,len)
+       struct mnem_list *list;
+       int len;
+{
+       struct mnem_elem **p;
+       int i;
+       p = (struct mnem_elem **)Malloc(len*sizeof(struct mnem_elem *));
+       while(len--) {
+               p[len] = list->elem;
+               list = list->next;
+       }
+       return(p);
+}
+
+struct mnem_list *
+addelem(oldlist, mnem, test)
+       struct mnem_list *oldlist;
+       struct idf *mnem;
+       struct exp_node *test;
+{
+       struct mnem_list *reslist;
+       struct mnem_elem *element;
+       element = (struct mnem_elem *)Malloc(sizeof(struct mnem_elem));
+       element->op_code = mnem;
+       element->arg = test;
+       reslist = (struct mnem_list *)Malloc(sizeof(struct mnem_list));
+       reslist->elem = element;
+       reslist->next = oldlist;
+       return(reslist);
+}
+
+int
+dotransition(state, mnem, mnem_list, lenlist)
+       int state;
+       struct idf *mnem;
+       struct mnem_list *mnem_list;
+       int lenlist;
+{
+       struct state *p;
+       /* look for existing transition */
+       for(p=states[state];
+           (p!=((struct state *)NULL)) && ((p->op)!=mnem);
+           p = p->next
+          );
+       if(p==(struct state *)NULL) {
+               /* none found so add a new state to dfa */
+               p=(struct state *)Malloc(sizeof(struct state));
+               p->op=mnem;
+               if(++higheststate>MAXSTATES) {
+                       fprint("Parser: More than %s states\n",MAXSTATES);
+                       sys_stop(S_EXIT);
+               }
+               p->goto_state= higheststate;
+               p->next=states[currentstate];
+               states[currentstate]=p;
+               states[higheststate] = (struct state *)NULL;
+               actions[higheststate] = (struct action *)NULL;
+               patterns[higheststate].m_len = lencurrpatt;
+               patterns[higheststate].m_elems =
+                       constructlist(mnem_list,lenlist);
+               return(higheststate);
+       }
+       else return(p->goto_state); /* already exists */
+}
+
+struct exp_node *
+combinetests(test1, test2)
+       struct exp_node *test1, *test2;
+{
+       if(test1==(struct exp_node *)NULL)
+               return(test2);
+       else if(test2==(struct exp_node *)NULL)
+               return(test1);
+       else
+               return(mknode(LOGAND,test1,test2));
+}
+
+priority(op) int op; {
+       switch (op) {
+       case LOGOR:     return(1);
+       case LOGAND:    return(2);
+       case BITOR:     return(3);
+       case XOR:       return(4);
+       case BITAND:    return(5);
+       case EQ:
+       case NE:        return(6);
+       case LT:
+       case LE:
+       case GT:
+       case GE:        return(7);
+       case LSHIFT:
+       case RSHIFT:    return(8);
+       case MINUS:
+       case PLUS:      return(9);
+       case TIMES:
+       case DIV:
+       case MOD:       return(10);
+       case NOT:
+       case COMP:
+       case UPLUS:
+       case UMINUS:    return(11);
+       }
+}
+
+struct exp_node *
+mknode(op,left,right)
+       int op;
+       struct exp_node *left,*right;
+{
+       struct exp_node *p;
+       p = (struct exp_node *)Malloc(sizeof(struct exp_node));
+       p->node_type = op;
+       p->exp_left = left;
+       p->exp_right = right;
+       return(p);
+}
+
+struct exp_node *
+mkleaf(op,val)
+       int op,val;
+{      
+       struct exp_node *p;
+       p = (struct exp_node *)Malloc(sizeof(struct exp_node));
+       p->node_type = op;
+       p->leaf_val = val;
+       return(p);
+}
+
+LLmessage(insertedtok)
+       int insertedtok;
+{
+       nerrors++;
+       fprint(STDERR,"parser: syntax error on line %d: ",linenum);
+       if(insertedtok) {
+               fprint(STDERR,"Inserted token %d\n",insertedtok);
+               yyless(0);
+       }
+       else fprint(STDERR,"Deleted token %d\n",LLsymb);
+}
+
+main() {
+       initlex();
+       states[0] = (struct state *)NULL;
+       patterns[0].m_len = 0;
+       parser();
+       if(nerrors) {
+               fprint(STDERR,"%d errors detected\n",nerrors);
+               sys_stop(S_EXIT);
+       }
+       outputnopt();
+       sys_stop(S_END);
+}
+}
diff --git a/modules/src/em_opt/parser.h b/modules/src/em_opt/parser.h
new file mode 100644 (file)
index 0000000..6df6ef3
--- /dev/null
@@ -0,0 +1,96 @@
+/* $Header$ */
+#include <system.h>
+
+#define NULL 0
+
+/* type of arguments expected by each instruction */
+#define NOARG  1
+#define CST    2
+#define CSTOPT 3
+#define LAB    4
+#define DEFILB 5
+#define PNAM   6
+#define EXT    7
+
+#define        IDF_TYPE struct id_info
+struct id_info {
+       struct idf *nextidf;    /* chain all opcodes together */
+       int used;               /* is this op used? */
+       int startpatt;          /* does it start a pattern? */
+       int opcode;             /* opcode of operator */
+       int argfmt;             /* how to access pattern argument */
+#define id_nextidf     id_user.nextidf
+#define id_used                id_user.used
+#define id_startpatt   id_user.startpatt
+#define id_opcode      id_user.opcode
+#define id_argfmt      id_user.argfmt
+};
+#include <idf_pkg.spec>
+
+struct exp_node {
+       int node_type;
+       union {
+               struct {
+                       struct exp_node *left;
+                       struct exp_node *right;
+               } interior;
+               int val;
+       } node_args;
+#define exp_left node_args.interior.left
+#define exp_right node_args.interior.right
+#define leaf_val node_args.val
+};
+
+struct mnem_elem {
+       struct idf *op_code;
+       struct exp_node *arg;   /* optional arg expression if replacement */
+};
+
+struct mnem_list {
+       struct mnem_list *next; /* cdr of list */
+       struct mnem_elem *elem; /* car of list */
+};
+
+struct mnems {
+       int m_len;                      /* number of mnem's in pattern */
+       struct mnem_elem **m_elems;     /* array of mnem's */
+};
+
+struct action {
+       struct action *next;    /* chain all actions for same state together */
+       int linenum;                    /* line number in patterns */
+       struct exp_node *test;          /* test expression (if any) */
+       struct mnems replacement;       /* replacement pattern */
+};
+
+struct state {
+       struct state *next;     /* chain to next entry for this state */
+       struct idf *op;         /* transition on op to.. */
+       int goto_state;         /* state 'goto_state' */
+};
+
+#define MAXSTATES      2000
+#define MAXPATTERN     20
+
+/* Parser globals */
+extern struct state *states[MAXSTATES];
+extern struct action *actions[MAXSTATES];
+extern struct mnems patterns[MAXSTATES];
+extern int higheststate;               /* Highest state yet allocated */
+extern struct idf *ops;                        /* Chained list of all ops */
+extern int longestpattern;
+extern int nerrors;
+extern File *ofile;
+
+/* Lexical analyser globals */
+extern struct idf *opval;      /* opcode of returned OPCODE*/
+extern int lastintval;         /* value of last integer seen */
+extern int     linenum;        /*line number of input file*/
+
+/* Functions not returning int */
+char *Malloc();
+struct exp_node *mknode();
+struct exp_node *mkleaf();
+struct exp_node *combinetests();
+struct mnem_list *addelem();
+struct mnem_elem **constructlist();
diff --git a/modules/src/em_opt/patterns b/modules/src/em_opt/patterns
new file mode 100644 (file)
index 0000000..c2f62f8
--- /dev/null
@@ -0,0 +1,569 @@
+/* $Header$ */
+loc adi w loc sbi w : loc $1-$3 adi w
+inc dec:
+inc loc adi w :        loc $2+1 adi w
+inc loc sbi w :        loc $2-1 sbi w
+dec loc adi w :        loc $2-1 adi w
+dec loc sbi w :        loc $2+1 sbi w
+ldc adi 2*w ldc sbi 2*w : ldc $1-$3 adi 2*w
+loc adi w loc adi w : loc $1+$3 adi w
+ldc adi 2*w ldc adi 2*w : ldc $1+$3 adi 2*w
+loc adi w loc mli w :  loc $3 mli w loc $1*$3 adi w
+loc adi w loc 1 sli w : loc $3 sli w loc 2*$1 adi w
+adp 0 :
+adp adp : adp $1+$2
+adp lof : lof $1+$2
+adp ldf : ldf $1+$2
+adp !=0 loi w : lof $1
+adp !=0 loi 2*w : ldf $1
+adp stf : stf $1+$2
+adp sdf : sdf $1+$2
+adp !=0 sti w : stf $1
+adp !=0 sti 2*w : sdf $1
+asp 0 :
+asp asp : asp $1+$2
+blm 0 : asp 2*p
+cmi w zeq : beq $2
+cmi w zge : bge $2
+cmi w zgt : bgt $2
+cmi w zle : ble $2
+cmi w zlt : blt $2
+cmi w zne : bne $2
+cmu w zeq :    beq $2
+cmu w zne :    bne $2
+dvi ngi $1 : ngi $1 dvi $1
+lae adp : lae $1+$2
+lae blm w : loi w ste $1
+lae blm 2*w : loi 2*w sde $1
+lae ldf : lde $1+$2
+lae lof : loe $1+$2
+lae loi w : loe $1
+lae loi 2*w : lde $1
+#ifdef INT
+lae loi loe $1-w ? $2%w==0: lae $3 loi $2+w
+lae loi lde $1-2*w ? $2%w==0: lae $3 loi $2+2*w
+lae $3+$4 loi lae loi ? $2%w==0 && $4%w==0: lae $3 loi $2+$4
+lae sti ste $1+$2 : lae $1 sti $2+w
+lae sti sde $1+$2 : lae $1 sti $2+2*w
+lae sti loc ste $1-w : loc $3 lae $4 sti $2+w
+lae sti lol ste $1-w : lol $3 lae $4 sti $2+w
+#endif
+lae lae blm loe $1+$3 ste $2+$3 : lae $1 lae $2 blm $3+w
+lae lae blm lde $1+$3 sde $2+$3 : lae $1 lae $2 blm $3+2*w
+lae lae blm lae $1+$3 lae $2+$3 blm : lae $1 lae $2 blm $3+$6
+lae lal blm lae $1+$3 lal $2+$3 blm ? samesign($2,$5):
+       lae $1 lal $2 blm $3+$6
+lal lae blm lal $1+$3 lae $2+$3 blm ? samesign($1,$4):
+       lal $1 lae $2 blm $3+$6
+lal lal blm lal $1+$3 lal $2+$3 blm ? samesign($1,$4) && samesign($2,$5):
+       lal $1 lal $2 blm $3+$6
+lal lal sbs w ? samesign($1,$2): loc $1-$2
+lae sdf : sde $1+$2
+lae stf : ste $1+$2
+lae sti w : ste $1
+lae sti 2*w : sde $1
+lal adp ? samesign($1,$1+$2): lal $1+$2
+lal blm w : loi w stl $1
+lal blm 2*w : loi 2*w sdl $1
+#ifdef INT
+/*lal sti loc stl $1-w ? notreg($4) && samesign($1,$4):        */
+/*     loc $3 lal $4 sti $2+w                          */
+/*lal sti loe stl $1-w ? notreg($4) && samesign($1,$4):        */
+/*     loe $3 lal $4 sti $2+w                          */
+#endif
+lal ldf ? samesign($1,$1+$2): ldl $1+$2
+lal lof ? samesign($1,$1+$2): lol $1+$2
+lal loi w : lol $1
+lal loi 2*w : ldl $1
+#ifdef INT
+/*lal loi lol $1-w ? notreg($3) && samesign($1,$3) && $2%w==0:         */
+/*     lal $3 loi $2+w                                         */
+/*lal loi ldl $1-2*w ? notreg($3) && samesign($1,$3) && $2%w==0:       */
+/*     lal $3 loi $2+2*w                                               */
+lal loi lal loi $1-$3 ? samesign($1,$3) && $2%w==0 && $4%w==0:
+       lal $3 loi $2+$4
+/*lal sti stl $1+$2 ? notreg($3) && samesign($1,$3): lal $1 sti $2+w   */
+/*lal sti sdl $1+$2 ? notreg($3) && samesign($1,$3): lal $1 sti $2+2*w*/
+#endif
+lal sdf ? samesign($1,$1+$2): sdl $1+$2
+lal stf ? samesign($1,$1+$2): stl $1+$2
+lal sti w : stl $1
+lal sti 2*w : sdl $1
+#ifdef INT
+lde lde $1-2*w : lae $2 loi 4*w
+lde loe $1-w : lae $2 loi 3*w
+#endif
+lde sde $1 :
+lde sde lde $1+2*w sde $2+2*w : lae $1 lae $2 blm 4*w
+#ifdef INT
+/*ldl ldl $1-2*w ? notreg($1) && notreg($2) && samesign($1,$2):*/
+/*     lal $2 loi 4*w                                          */
+/*ldl lol $1-w ? notreg($1) && notreg($2) && samesign($1,$2):  */
+/*     lal $2 loi 3*w                                          */
+#endif
+ldl sdl $1:
+lxa loi lxa $1 sti $2 :
+lxa lof lxa $1 stf $2 :
+lxa ldf lxa $1 sdf $2 :
+lxa >1 stf lxa $1 lof $2 : dup w lxa $1 stf $2
+lxa >1 sdf lxa $1 ldf $2 : dup 2*w lxa $1 sdf $2
+lxl lof lxl $1 stf $2 :
+lxl ldf lxl $1 sdf $2 :
+lxl >1 stf lxl $1 lof $2 : dup w lxl $1 stf $2
+lxl >1 sdf lxl $1 ldf $2 : dup 2*w lxl $1 sdf $2
+lxa >1 sti lxa $1 loi $2 ? $2%w==0: dup $2 lxa $1 sti $2
+loc -1 adi w : dec
+loc dec ? sfit($1-1,8*w) :     loc $1-1
+loc -1 bgt : zge $2
+loc -1 ble : zlt $2
+loc -1 dvi w : ngi w
+ldc -1 dvi 2*w : ngi 2*w
+loc -1 loe adi w : loe $2 dec
+loc -1 lol adi w : lol $2 dec
+loc -1 mli w : ngi w
+ldc -1 mli 2*w : ngi 2*w
+loc -1 sbi w : inc
+loc inc ? sfit($1+1,8*w) :     loc $1+1
+loc 0 adi w :
+ldc 0 adi 2*w :
+loc 0 ads w :
+ldc 0 ads 2*w :
+zer adi $1 :
+loc 0 beq : zeq $2
+loc 0 bge : zge $2
+loc 0 bgt : zgt $2
+loc 0 ble : zle $2
+loc 0 blt : zlt $2
+loc 0 bne : zne $2
+loc 0 cmi w teq : teq
+loc 0 cmi w tge : tge
+loc 0 cmi w tgt : tgt
+loc 0 cmi w tle : tle
+loc 0 cmi w tlt : tlt
+loc 0 cmi w tne : tne
+loc 0 cmu w teq :      teq
+loc 0 cmu w tne :      tne
+loc 0 cmu w zeq :      zeq $3
+loc 0 cmu w zne :      zne $3
+loc 0 ior w :
+ldc 0 ior 2*w :
+zer ior $1 :
+loc 0 ste : zre $2
+loc 0 stl : zrl $2
+loc 0 sbi w :
+ldc 0 sbi 2*w :
+zer sbi $1 :
+loc 0 xor w :
+ldc 0 xor 2*w :
+zer xor $1 :
+loc 1 adi w : inc
+loc 1 bge : zgt $2
+loc 1 blt : zle $2
+loc 1 dvi w :
+ldc 1 dvi 2*w :
+loc 1 dvu w :
+loc 1 dvu 2*w :
+loc 1 loe adi w : loe $2 inc
+loc 1 lol adi w : lol $2 inc
+loc 0 mli w :  asp w loc 0
+ldc 0 mli 2*w :        asp 2*w ldc 0
+loc 0 mlu w : asp w loc 0
+ldc 0 mlu 2*w :        asp 2*w ldc 0
+loc 1 mli w :
+ldc 1 mli 2*w :
+loc 1  mlu w  :
+ldc 1  mlu 2*w  :
+loc 1  sbi w  : dec
+loc loe mli w :      loe $2  loc $1  mli w
+loc loe adi w loc :    loe $2  loc $1  adi w loc $4
+loc loe adi w inc :    loe $2  loc $1  adi w inc
+loc loe adi w dec :    loe $2  loc $1  adi w dec
+loc lol mli w :      lol $2  loc $1  mli w
+loc lol adi w loc :    lol $2  loc $1  adi w loc $4
+loc lol adi w inc :    lol $2  loc $1  adi w dec
+loc lol adi w dec :    lol $2  loc $1  adi w dec
+ldc lde mli 2*w :    lde $2  ldc $1  mli 2*w
+ldc lde adi 2*w :    lde $2  ldc $1  adi 2*w
+ldc ldl mli 2*w :    ldl $2  ldc $1  mli 2*w
+ldc ldl adi 2*w :    ldl $2  ldc $1  adi 2*w
+loc 2  mli w  :        loc 1   sli w
+loc 4  mli w  :        loc 2   sli w
+loc 8  mli w  :        loc 3   sli w
+loc 16  mli w  :        loc 4   sli w
+loc 32  mli w  :        loc 5   sli w
+loc 64  mli w  :        loc 6   sli w
+loc 128  mli w  :       loc 7   sli w
+loc 256  mli w  :       loc 8   sli w
+loc 2  mlu w  :        loc 1   slu w
+loc 4  mlu w  :        loc 2   slu w
+loc 8  mlu w  :        loc 3   slu w
+loc 16  mlu w  :        loc 4   slu w
+loc 32  mlu w  :        loc 5   slu w
+loc 64  mlu w  :        loc 6   slu w
+loc 128  mlu w  :       loc 7   slu w
+loc 256  mlu w  :       loc 8   slu w
+loc adi undefined :   adi $1
+loc sbi undefined :   sbi $1
+loc mli undefined :   mli $1
+loc dvi undefined :   dvi $1
+loc rmi undefined :   rmi $1
+loc ngi undefined :   ngi $1
+loc sli undefined :   sli $1
+loc sri undefined :   sri $1
+loc adu undefined :   adu $1
+loc sbu undefined :   sbu $1
+loc mlu undefined :   mlu $1
+loc dvu undefined :   dvu $1
+loc rmu undefined :   rmu $1
+loc slu undefined :   slu $1
+loc sru undefined :   sru $1
+loc adf undefined :   adf $1
+loc sbf undefined :   sbf $1
+loc mlf undefined :   mlf $1
+loc dvf undefined :   dvf $1
+loc ngf undefined :   ngf $1
+loc fif undefined :   fif $1
+loc fef undefined :   fef $1
+loc zer undefined :   zer $1
+loc zrf undefined :   zrf $1
+loc los w :    loi $1
+loc sts w :    sti $1
+loc ads w :    adp $1
+ldc ads 2*w ? sfit($1,8*w):    adp $1
+loc ass w :    asp $1
+loc bls w :    blm $1
+loc dus w :    dup $1
+loc loc $1 cii :
+loc loc $1 cuu :
+loc loc $1 cff :
+loc and undefined :   and $1
+loc ior undefined :   ior $1
+loc xor undefined :   xor $1
+loc com undefined :   com $1
+loc rol undefined :   rol $1
+loc 0 rol :
+loc ror undefined :   ror $1
+loc 0 ror :
+loc inn undefined :   inn $1
+loc set undefined :   set $1
+loc cmi undefined :   cmi $1
+loc cmu undefined :   cmu $1
+loc cmf undefined :   cmf $1
+loe dec ste $1:     dee $1
+loe inc ste $1:     ine $1
+loe loc 0  mli w  :     loc 0
+#ifdef INT
+loe loe $1-w :       lde $2
+loe loe $1+w beq :   lde $1  beq $3
+loe loe $1+w bge :   lde $1  ble $3
+loe loe $1+w bgt :   lde $1  blt $3
+loe loe $1+w ble :   lde $1  bge $3
+loe loe $1+w blt :   lde $1  bgt $3
+loe loe $1+w bne :   lde $1  bne $3
+loe loe $1+w  cmi w  :  lde $1  cmi w   ngi w
+#endif
+ngi w teq :  teq
+ngi w tge :  tle
+ngi w tgt :  tlt
+ngi w tle :  tge
+ngi w tlt :  tgt
+ngi w tne :  tne
+#ifdef INT
+loe loe $1+w  mli w  :  lde $1  mli w
+loe loe $1+w  adi w  :  lde $1  adi w
+loe loe $1 : loe $1  dup w
+#endif
+loe ste $1 :
+lol blm w ? p==w : loi w   sil $1
+ldl blm w ? p==2*w :  loi w   sil $1
+lol dec stl $1 :     del $1
+lol inc stl $1 :     inl $1
+lol loc 0  mli w  :     loc 0
+lol loi w ? w==p :  lil $1
+ldl loi w ? p==2*w :  lil $1
+#ifdef INT
+/*lol lol $1-w ? notreg($1) && notreg($2) && samesign($1,$2):          */
+/*     ldl $2                                                          */
+/*lol lol $1+w  beq ? notreg($1) && notreg($2) && samesign($1,$2):     */
+/*     ldl $1  beq $3                                                  */
+/*lol lol $1+w  bge ? notreg($1) && notreg($2) && samesign($1,$2):     */
+/*     ldl $1  ble $3                                                  */
+/*lol lol $1+w  bgt ? notreg($1) && notreg($2) && samesign($1,$2):     */
+/*     ldl $1  blt $3                                                  */
+/*lol lol $1+w  ble ? notreg($1) && notreg($2) && samesign($1,$2):     */
+/*     ldl $1  bge $3                                                  */
+/*lol lol $1+w  blt ? notreg($1) && notreg($2) && samesign($1,$2):     */
+/*     ldl $1  bgt $3                                                  */
+/*lol lol $1+w  bne ? notreg($1) && notreg($2) && samesign($1,$2):     */
+/*     ldl $1  bne $3                                                  */
+/*lol lol $1+w  cmi w ?   notreg($1) && notreg($2) && samesign($1,$2): */
+/*     ldl $1  cmi w   ngi w                                           */
+/*lol lol $1+w  mli w ?   notreg($1) && notreg($2) && samesign($1,$2): */
+/*     ldl $1  mli w                                                   */
+/*lol lol $1+w  adi w ?   notreg($1) && notreg($2) && samesign($1,$2): */
+/*     ldl $1  adi w                                                   */
+lol lol $1 : lol $1  dup w
+#endif
+lol stl $1:
+lol  sti w ? p==w :  sil $1
+ldl sti w ? p==2*w :  sil $1
+mli ngi $1: ngi $1  mli $1
+ngi adi $1: sbi $1
+ngf adf $1: sbf $1
+ngi sbi $1: adi $1
+ngf sbf $1: adf $1
+ngi ngi $1:
+ngf ngf $1:
+#ifdef INT
+sde sde $1+2*w :     lae $1  sti 4*w
+sde ste $1+2*w :     lae $1  sti 3*w
+sde loc ste $1-w :   loc $2  lae $3  sti 3*w
+sde lol ste $1-w :   lol $2  lae $3  sti 3*w
+sde lde $1 : dup 2*w sde $1
+#endif
+sdf 0 :      sti 2*w
+#ifdef INT
+/*sdl sdl $1+2*w ? notreg($1) && notreg($2) && samesign($1,$2):                */
+/*     lal $1  sti 4*w                                                 */
+/*sdl stl $1+2*w ? notreg($1) && notreg($2) && samesign($1,$2):                */
+/*     lal $1  sti 3*w                                                 */
+/*sdl loc stl $1-w ? notreg($1) && notreg($3) && samesign($1,$3):      */
+/*     loc $2  lal $3  sti 3*w                                         */
+/*sdl loe stl $1-w ? notreg($1) && notreg($3) && samesign($1,$3):      */
+/*     loe $2  lal $3  sti 3*w                                         */
+sdl ldl $1 : dup 2*w sdl $1
+ste loe $1 : dup w   ste $1
+ste ste $1-w :       sde $2
+ste loc ste $1-w :   loc $2  sde $3
+ste lol ste $1-w :   lol $2  sde $3
+stl lol $1 : dup w   stl $1
+#endif
+stf 0 : sti w
+sdl ldl $1 ret 2*w  :  ret 2*w
+#ifdef INT
+/*stl stl $1+w ? notreg($1) && notreg($2) && samesign($1,$2):  sdl $1  */
+/*stl loc stl $1-w ? notreg($1) && notreg($3) && samesign($1,$3):      */
+/*     loc $2  sdl $3                                                  */
+/*stl loe stl $1-w ? notreg($1) && notreg($3) && samesign($1,$3):      */
+/*     loe $2  sdl $3                                                  */
+#endif
+stl lol $1 ret w  :    ret w
+lal sti lal $1 loi $2 ret $2 : ret $2
+loc sbi w  loc sbi w  : loc $1+$3 sbi w
+ldc sbi 2*w  ldc sbi 2*w  :     ldc $1+$3 sbi 2*w
+loc sbi w  loc adi w  : loc $1-$3 sbi w
+ldc sbi 2*w  ldc adi 2*w  :     ldc $1-$3 sbi 2*w
+loc sbi w  loc mli w  :        loc $3 mli w loc $1*$3 sbi w
+loc sbi w  loc 1 sli w    : loc $3 sli w loc 2*$1 sbi w
+teq teq :       tne
+teq tne :       teq
+teq zne :       zeq $2
+teq zeq :       zne $2
+tge teq :       tlt
+tge tne :       tge
+tge zeq :       zlt $2
+tge zne :       zge $2
+tgt teq :       tle
+tgt tne :       tgt
+tgt zeq :       zle $2
+tgt zne :       zgt $2
+tle teq :       tgt
+tle tne :       tle
+tle zeq :       zgt $2
+tle zne :       zle $2
+tlt teq :       tge
+tlt tne :       tlt
+tlt zeq :       zge $2
+tlt zne :       zlt $2
+tne teq :       teq
+tne tne :       tne
+tne zeq :       zeq $2
+tne zne :       zne $2
+#ifdef INT
+loc 0  loc 0  loc 0    :    zer 3*w
+zer defined loc 0 :   zer $1+w
+#endif
+loi 1  loc and w  ? ($2&255)==255:    loi 1
+loi <w loc w loc cii : loi $1 loc $2 loc $3 cui
+loi 1  loc 1  loc w  cii loc 255  and w     :  loi 1
+loi 1  loc 1  loc w  cii loc cmi w zeq ? $5>=0&&$5<128 :       loi 1 loc $5 cmi w zeq $7
+loi 1  loc 1  loc w  cii loc cmi w zne ? $5>=0&&$5<128 :       loi 1 loc $5 cmi w zne $7
+loi 1  loc 1  loc w  cii loc w  loc w  ciu loc 255 and w:      loi 1
+cmp teq :       cms p   teq
+cmp tne :       cms p   tne
+cmu defined teq :    cms $1  teq
+cmu defined tne :    cms $1  tne
+cms w zeq :  beq $2
+cms w zne :  bne $2
+lol lae aar w adp :  adp $4  lol $1  lae $2  aar w
+loe lae aar w adp :  adp $4  loe $1  lae $2  aar w
+cmi defined zeq :    cms $1  zeq $2
+cmi defined zne :    cms $1  zne $2
+#ifdef INT
+loe $4  inc dup w ste  :        ine $1  loe $1
+loe $4  dec dup w ste  :        dee $1  loe $1
+lol $4  inc dup w stl  :        inl $1  lol $1
+lol $4  dec dup w stl  :        del $1  lol $1
+adp dup p ste adp -$1 ? p==w : dup p adp $1 ste $3
+adp dup p sde adp -$1 ? p==2*w : dup p adp $1 sde $3
+adp dup p stl adp -$1 ? p==w :       dup p   adp $1   stl $3
+adp dup p sdl adp -$1 ? p==2*w :       dup p   adp $1   sdl $3
+inc dup w ste dec :  dup w   inc     ste $3
+inc dup w stl dec :  dup w   inc     stl $3
+#endif
+zeq bra lab $1 :     zne $2  lab $1
+zge bra lab $1:     zlt $2  lab $1
+zgt bra lab $1 :     zle $2  lab $1
+zlt bra lab $1 :     zge $2  lab $1
+zle bra lab $1 :     zgt $2  lab $1
+zne bra lab $1 :     zeq $2  lab $1
+beq bra lab $1 :     bne $2  lab $1
+bge bra lab $1 :     blt $2  lab $1
+bgt bra lab $1 :     ble $2  lab $1
+blt bra lab $1 :     bge $2  lab $1
+ble bra lab $1 :     bgt $2  lab $1
+bne bra lab $1 :     beq $2  lab $1
+lin lin :       lin $2
+lin lab lin :   lab $2  lin $3
+lin ret :       ret $2
+lin bra :       bra $2
+#ifdef INT
+dup p  stl loi w ? p==w :     stl $2  lil $2
+dup p  sdl loi w  ? p==2*w :     sdl $2  lil $2
+dup p  stl sti w ? p==w :     stl $2  sil $2
+dup p  sdl sti w ? p==2*w  :     sdl $2  sil $2
+#endif
+loc 0  cms w  : tne
+zer w : loc 0
+loc loc adi w ? sfit($1+$2,8*w) : loc $1+$2
+loc loc sbi w ? sfit($1-$2,8*w) : loc $1-$2
+loc loc mli w ? sfit($1*$2,8*w) : loc $1*$2
+loc loc !=0 dvi w : loc $1/$2
+loc loc and w  :       loc $1&$2
+loc loc ior w  :       loc $1|$2
+loc 0  loc 0  ior 2*w    :     
+loc loc xor w  :       loc $1^$2
+loc 0  loc 0  xor 2*w    :     
+loc loc rol w  :       loc rotate($1,$2)
+loc loc ror w  :       loc rotate($1,8*w-$2)
+loc ngi w ? sfit(-$1,8*w) : loc -$1
+loc com w  :   loc ~$1
+ldc ngi 2*w  : ldc -$1
+/*loc lae aar w ? $1>=rom(2,0) && $1 <= rom(2,0)+rom(2,1) :    */
+/*     adp ($1-rom(2,0))*rom(2,2)                              */
+/*loc lae lar w ? $1>=rom(2,0) && $1 <= rom(2,0)+rom(2,1) :    */
+/*     adp ($1-rom(2,0))*rom(2,2) loi rom(2,2)                 */
+/*loc lae sar w ? $1>=rom(2,0) && $1 <= rom(2,0)+rom(2,1) :    */
+/*     adp ($1-rom(2,0))*rom(2,2) sti rom(2,2)                 */
+loc teq : loc $1==0
+loc tne : loc $1!=0
+loc tge : loc $1>=0
+loc tle : loc $1<=0
+loc tgt : loc $1>0
+loc tlt : loc $1<0
+loc 0  zeq : bra $2
+loc zeq :
+loc !=0 zne : bra $2
+loc zne :
+loc >=0 zge : bra $2
+loc zge :
+loc <=0 zle : bra $2
+loc zle :
+loc >0 zgt : bra $2
+loc zgt :
+loc <0 zlt : bra $2
+loc zlt :
+loc loc $1 beq : bra $3
+loc loc beq :
+loc loc !=$1 bne : bra $3
+loc loc bne :
+loc loc bge ? $1>=$2 : bra $3
+loc loc bge :
+loc loc ble ? $1<=$2 : bra $3
+loc loc ble :
+loc loc bgt ? $1>$2 : bra $3
+loc loc bgt :
+loc loc blt ? $1<$2 : bra $3
+loc loc blt :
+lae loi >4*w lal sti $2  : lae $1 lal $3 blm $2
+lal loi >4*w lae sti $2  : lal $1 lae $3 blm $2
+lal loi >4*w lal sti $2  ? ( $3<=$1-$2 || $3>=$1+$2 ) :
+       lal $1 lal $3 blm $2
+lae loi >4*w lae sti $2 ? ($3<=$1-$2 || $3>=$1+$2) :
+       lae $1 lae $3 blm $2
+loc 0  loc w  loc cif  :       zrf $3
+loc >=0 loc w  loc 2*w  ciu :  ldc $1
+loc loc w  loc 2*w  cii  :     ldc $1
+loi loc >=0 inn $1 ? $2<$1*8 : 
+       lof ($2/(8*w))*w loc $2&(8*w-1) inn w
+ldl loc >=0  inn 2*w ? $2<16*w : 
+       lol $1+($2/(8*w))*w loc $2&(8*w-1) inn w
+lde loc >=0 inn 2*w ? $2<16*w : 
+       loe $1+($2/(8*w))*w loc $2&(8*w-1) inn w
+ldf loc >=0 inn 2*w ? $2<16*w : 
+       lof $1+($2/(8*w))*w loc $2&(8*w-1) inn w
+loc inn ? $1<0 || $1>=8*$2 : asp $2 loc 0
+lol loc adi w  stl $1 : loc $2 lol $1 adi w stl $4
+lol loe adi w  stl $1 : loe $2 lol $1 adi w stl $4
+lol lol !=$1 adi w  stl $1  : lol $2 lol $1 adi w stl $4
+loe loc adi w  ste $1 : loc $2 loe $1 adi w ste $4
+loe loe !=$1 adi w  ste $1  : loe $2 loe $1 adi w ste $4
+loe lol adi w  ste $1 : lol $2 loe $1 adi w ste $4
+lol loc ior w  stl $1 : loc $2 lol $1 ior w stl $4
+lol loe ior w  stl $1 : loe $2 lol $1 ior w stl $4
+lol lol !=$1 ior w  stl $1  : lol $2 lol $1 ior w stl $4
+loe loc ior w  ste $1 : loc $2 loe $1 ior w ste $4
+loe loe !=$1 ior w  ste $1  : loe $2 loe $1 ior w ste $4
+loe lol ior w  ste $1 : lol $2 loe $1 ior w ste $4
+lol loc and w  stl $1 : loc $2 lol $1 and w stl $4
+lol loe and w  stl $1 : loe $2 lol $1 and w stl $4
+lol lol !=$1 and w  stl $1  : lol $2 lol $1 and w stl $4
+loe loc and w  ste $1 : loc $2 loe $1 and w ste $4
+loe loe !=$1 and w  ste $1  : loe $2 loe $1 and w ste $4
+loe lol and w  ste $1 : lol $2 loe $1 and w ste $4
+loi asp $1 : asp p
+lal loi 4*w loc loc loc loc ior 4*w ? ($3==0)+($4==0)+($5==0)+($6==0)>2 :
+       lol $1+3*w loc $3 ior w lol $1+2*w loc $4 ior w lol $1+w loc $5 ior w lol $1 loc $6 ior w
+loc dup 2  stl loc dup 2 stl  :
+       loc $1 stl $3 loc $4 stl $6 loc $1 loc $4
+/*LLP LLP adp SLP $2 sti ? (!notreg($2) || $5!=p):     */
+/*     LLP $1 sti $5 LLP $2 adp $3 SLP $4              */
+loe loe adp ste $2 sti !=p ? p==w : loe $1 sti $5 loe $2 adp $3 ste $4
+lde lde adp sde $2 sti !=p ? p==2*w : lde $1 sti $5 lde $2 adp $3 sde $4
+#ifndef INT
+dup w  stl : stl $2 lol $2
+dup w  ste : ste $2 loe $2
+dup w  sil : sil $2 lil $2
+dup w  loe sti w ? p==w  : loe $2 sti w loe $2 loi w
+dup w  lde sti w ? p==2*w  : lde $2 sti w lde $2 loi w
+dup w  lol stf ? p==w : lol $2 stf $3 lol $2 lof $3
+dup w  ldl stf ? p==2*w : ldl $2 stf $3 ldl $2 lof $3
+dup w  loe stf ? p==w : loe $2 stf $3 loe $2 lof $3
+dup w  lde stf ? p==2*w : lde $2 stf $3 lde $2 lof $3
+dup 2*w  sdl : sdl $2 ldl $2
+dup 2*w  sde : sde $2 lde $2
+dup 2*w  lol sti 2*w ? p==w  : lol $2 sti 2*w lol $2 loi 2*w
+dup 2*w  ldl sti 2*w ? p==2*w  : ldl $2 sti 2*w ldl $2 loi 2*w
+dup 2*w  loe sti 2*w ? p==w  : loe $2 sti 2*w loe $2 loi 2*w
+dup 2*w  lde sti 2*w ? p==2*w  : lde $2 sti 2*w lde $2 loi 2*w
+dup 2*w  lol sdf ? p==w : lol $2 sdf $3 lol $2 ldf $3
+dup 2*w  ldl sdf ? p==2*w : ldl $2 sdf $3 ldl $2 ldf $3
+dup 2*w  loe sdf ? p==w : loe $2 sdf $3 loe $2 ldf $3
+dup 2*w  lde sdf ? p==2*w : lde $2 sdf $3 lde $2 ldf $3
+lol dup w  : lol $1 lol $1
+loe dup w  : loe $1 loe $1
+lil dup w  : lil $1 lil $1
+loe loi w  dup 2 ? p==w  : loe $1 loi w loe $1 loi w
+lde loi w  dup 2 ? p==2*w  : lde $1 loi w lde $1 loi w
+ldl dup 2*w  : ldl $1 ldl $1
+lde dup 2*w  : lde $1 lde $1
+#endif
+adp stl lol $2 adp -$1 ? p==w : dup p adp $1 stl $2
+adp sdl ldl $2 adp -$1 ? p==2*w : dup p adp $1 sdl $2
+adp ste loe $2 adp -$1 ? p==w : dup p adp $1 ste $2
+adp sde lde $2 adp -$1 ? p==2*w : dup p adp $1 sde $2
+adp sil lil $2 adp -$1 ? p==w : dup p adp $1 sil $2
+adp lol sti p  lol $2 loi p  adp -$1 ? p==w : dup p adp $1 lol $2 sti p
+adp ldl sti p  ldl $2 loi p  adp -$1 ? p==2*w : dup p adp $1 ldl $2 sti p
+adp loe sti p  loe $2 loi p  adp -$1 ? p==w : dup p adp $1 loe $2 sti p
+adp lde sti p  lde $2 loi p  adp -$1 ? p==2*w : dup p adp $1 lde $2 sti p
diff --git a/modules/src/em_opt/pseudo.r b/modules/src/em_opt/pseudo.r
new file mode 100644 (file)
index 0000000..5e4d609
--- /dev/null
@@ -0,0 +1,471 @@
+#ifndef NORCSID
+static char rcsid[] = "$Header$";
+#endif
+
+#include "nopt.h"
+
+C_df_dlb(l)
+       label l;
+{
+       FLUSHDFA();
+       O_df_dlb(l);
+}
+
+C_df_dnam(s)
+       char * s;
+{
+       FLUSHDFA();
+       O_df_dnam(s);
+}
+
+C_pro(s,l)
+       char * s;
+       arith l;
+{
+       FLUSHDFA();
+       O_pro(s,l);
+}
+
+C_pro_narg(s)
+       char * s;
+{
+       FLUSHDFA();
+       O_pro_narg(s);
+}
+
+C_end(l)
+       arith l;
+{
+       FLUSHDFA();
+       O_end(l);
+}
+
+C_end_narg()
+{
+       FLUSHDFA();
+       O_end_narg();
+}
+
+C_exa_dnam(s)
+       char * s;
+{
+       FLUSHDFA();
+       O_exa_dnam(s);
+}
+
+C_exa_dlb(l)
+       label l;
+{
+       FLUSHDFA();
+       O_exa_dlb(l);
+}
+
+C_exp(s)
+       char * s;
+{
+       FLUSHDFA();
+       O_exp(s);
+}
+
+C_ina_dnam(s)
+       char * s;
+{
+       FLUSHDFA();
+       O_ina_dnam(s);
+}
+
+C_ina_dlb(l)
+       label l;
+{
+       FLUSHDFA();
+       O_ina_dlb(l);
+}
+
+C_inp(s)
+       char * s;
+{
+       FLUSHDFA();
+       O_inp(s);
+}
+
+C_bss_cst(n,w,i)
+       arith n;
+       arith w;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_cst(n,w,i);
+}
+
+C_bss_icon(n,s,sz,i)
+       arith n;
+       char * s;
+       arith sz;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_icon(n,s,sz,i);
+}
+
+C_bss_ucon(n,s,sz,i)
+       arith n;
+       char * s;
+       arith sz;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_ucon(n,s,sz,i);
+}
+
+C_bss_fcon(n,s,sz,i)
+       arith n;
+       char * s;
+       arith sz;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_fcon(n,s,sz,i);
+}
+
+C_bss_dnam(n,s,offs,i)
+       arith n;
+       char * s;
+       arith offs;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_dnam(n,s,offs,i);
+}
+
+C_bss_dlb(n,l,offs,i)
+       arith n;
+       label l;
+       arith offs;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_dlb(n,l,offs,i);
+}
+
+C_bss_ilb(n,l,i)
+       arith n;
+       label l;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_ilb(n,l,i);
+}
+
+C_bss_pnam(n,s,i)
+       arith n;
+       char * s;
+       int i;
+{
+       FLUSHDFA();
+       O_bss_pnam(n,s,i);
+}
+
+C_hol_cst(n,w,i)
+       arith n;
+       arith w;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_cst(n,w,i);
+}
+
+C_hol_icon(n,s,sz,i)
+       arith n;
+       char * s;
+       arith sz;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_icon(n,s,sz,i);
+}
+
+C_hol_ucon(n,s,sz,i)
+       arith n;
+       char * s;
+       arith sz;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_ucon(n,s,sz,i);
+}
+
+C_hol_fcon(n,s,sz,i)
+       arith n;
+       char * s;
+       arith sz;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_fcon(n,s,sz,i);
+}
+
+C_hol_dnam(n,s,offs,i)
+       arith n;
+       char * s;
+       arith offs;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_dnam(n,s,offs,i);
+}
+
+C_hol_dlb(n,l,offs,i)
+       arith n;
+       label l;
+       arith offs;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_dlb(n,l,offs,i);
+}
+
+C_hol_ilb(n,l,i)
+       arith n;
+       label l;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_ilb(n,l,i);
+}
+
+C_hol_pnam(n,s,i)
+       arith n;
+       char * s;
+       int i;
+{
+       FLUSHDFA();
+       O_hol_pnam(n,s,i);
+}
+
+C_con_cst(l)
+       arith l;
+{
+       FLUSHDFA();
+       O_con_cst(l);
+}
+
+C_con_icon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_con_icon(val,siz);
+}
+
+C_con_ucon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_con_ucon(val,siz);
+}
+
+C_con_fcon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_con_fcon(val,siz);
+}
+
+C_con_scon(str,siz)
+       char * str;
+       arith siz;
+{
+       FLUSHDFA();
+       O_con_scon(str,siz);
+}
+
+C_con_dnam(str,val)
+       char * str;
+       arith val;
+{
+       FLUSHDFA();
+       O_con_dnam(str,val);
+}
+
+C_con_dlb(l,val)
+       label l;
+       arith val;
+{
+       FLUSHDFA();
+       O_con_dlb(l,val);
+}
+
+C_con_ilb(l)
+       label l;
+{
+       FLUSHDFA();
+       O_con_ilb(l);
+}
+
+C_con_pnam(str)
+       char * str;
+{
+       FLUSHDFA();
+       O_con_pnam(str);
+}
+
+C_rom_cst(l)
+       arith l;
+{
+       FLUSHDFA();
+       O_rom_cst(l);
+}
+
+C_rom_icon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_rom_icon(val,siz);
+}
+
+C_rom_ucon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_rom_ucon(val,siz);
+}
+
+C_rom_fcon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_rom_fcon(val,siz);
+}
+
+C_rom_scon(str,siz)
+       char * str;
+       arith siz;
+{
+       FLUSHDFA();
+       O_rom_scon(str,siz);
+}
+
+C_rom_dnam(str,val)
+       char * str;
+       arith val;
+{
+       FLUSHDFA();
+       O_rom_dnam(str,val);
+}
+
+C_rom_dlb(l,val)
+       label l;
+       arith val;
+{
+       FLUSHDFA();
+       O_rom_dlb(l,val);
+}
+
+C_rom_ilb(l)
+       label l;
+{
+       FLUSHDFA();
+       O_rom_ilb(l);
+}
+
+C_rom_pnam(str)
+       char * str;
+{
+       FLUSHDFA();
+       O_rom_pnam(str);
+}
+
+C_cst(l)
+       arith l;
+{
+       FLUSHDFA();
+       O_cst(l);
+}
+
+C_icon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_icon(val,siz);
+}
+
+C_ucon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_ucon(val,siz);
+}
+
+C_fcon(val,siz)
+       char * val;
+       arith siz;
+{
+       FLUSHDFA();
+       O_fcon(val,siz);
+}
+
+C_scon(str,siz)
+       char * str;
+       arith siz;
+{
+       FLUSHDFA();
+       O_scon(str,siz);
+}
+
+C_dnam(str,val)
+       char * str;
+       arith val;
+{
+       FLUSHDFA();
+       O_dnam(str,val);
+}
+
+C_dlb(l,val)
+       label l;
+       arith val;
+{
+       FLUSHDFA();
+       O_dlb(l,val);
+}
+
+C_ilb(l)
+       label l;
+{
+       FLUSHDFA();
+       O_ilb(l);
+}
+
+C_pnam(str)
+       char * str;
+{
+       FLUSHDFA();
+       O_pnam(str);
+}
+
+C_mes_begin(ms)
+       int ms;
+{
+       FLUSHDFA();
+       O_mes_begin(ms);
+}
+
+C_mes_end()
+{
+       FLUSHDFA();
+       O_mes_end();
+}
+
+C_exc(c1,c2)
+       arith c1;
+       arith c2;
+{
+       FLUSHDFA();
+       O_exc(c1,c2);
+}
diff --git a/modules/src/em_opt/syntax.l b/modules/src/em_opt/syntax.l
new file mode 100644 (file)
index 0000000..be7dcbc
--- /dev/null
@@ -0,0 +1,59 @@
+%{
+/* $Header$ */
+#include "Lpars.h"
+#include "parser.h"
+
+struct idf *opval;     /* opcode of returned OPCODE*/
+int lastintval;                /* value of last integer seen */
+int linenum = 1;       /*current line number of input file*/
+%}
+%%
+sfit           return(SFIT);
+ufit           return(UFIT);
+rotate         return(ROTATE);
+p              return(PSIZE);
+w              return(WSIZE);
+defined                return(DEFINED);
+undefined      return(UNDEFINED);
+samesign       return(SAMESIGN);
+sameext                return(SAMEEXT);
+samenam                return(SAMENAM);
+offset         return(OFFSET);
+[a-z]*         {
+               opval = str2idf(yytext,0);
+               return(OPCODE);
+               }
+[0-9]+         {
+               lastintval = atoi(yytext);
+               return(INT);
+               }
+"$"            return(PATARG);
+"&&"           return(LOGAND);
+"||"           return(LOGOR);
+"&"            return(BITAND);
+"|"            return(BITOR);
+"^"            return(XOR);
+"-"            return(MINUS);
+"+"            return(PLUS);
+"*"            return(TIMES);
+"/"            return(DIV);
+"%"            return(MOD);
+"=="           return(EQ);
+"!="           return(NE);
+"<"            return(LT);
+"<="           return(LE);
+">"            return(GT);
+">="           return(GE);
+"<<"           return(LSHIFT);
+">>"           return(RSHIFT);
+"!"            return(NOT);
+"~"            return(COMP);
+","            return(COMMA);
+:[ \t]*\n[ \t]+        { linenum++; return(':'); }
+^"# "[0-9]+.*\n        { linenum=atoi(yytext+2); }
+^\#.*\n                { linenum++; }
+^\n            { linenum++; }
+[ \t]          ;
+\n             { linenum++; return(yytext[0]);}
+.              return(yytext[0]);
+%%