ANSI C conversion and add procedure declarations.

This commit is contained in:
carl 2019-05-11 01:17:40 +08:00
parent 472654c366
commit 21e15965cc
29 changed files with 2510 additions and 1970 deletions

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -9,20 +11,14 @@ static char rcsid[] = "$Id$";
#include "types.h" #include "types.h"
#include "tes.h" #include "tes.h"
#include "alloc.h" #include "alloc.h"
#include "util.h"
#include "line.h" #include "line.h"
#include "lookup.h" #include "lookup.h"
#include "proinf.h" #include "proinf.h"
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#ifdef USEMALLOC #ifdef USEMALLOC
short * myalloc(); short *myalloc(register unsigned int);
#define newcore(size) myalloc(size) #define newcore(size) myalloc(size)
#define oldcore(p,size) free(p) #define oldcore(p,size) free(p)
@ -94,9 +90,10 @@ int asizetab[] = {
* PART 1 * PART 1
*/ */
line_p newline(optyp) int optyp; { line_p newline(int optyp)
{
register line_p lnp; register line_p lnp;
register kind=optyp; register int kind = optyp;
if (kind > OPMINI) if (kind > OPMINI)
kind = OPMINI; kind = OPMINI;
@ -105,8 +102,9 @@ line_p newline(optyp) int optyp; {
return (lnp); return (lnp);
} }
oldline(lnp) register line_p lnp; { void oldline(register line_p lnp)
register kind=lnp->l_optyp&BMASK; {
register int kind = lnp->l_optyp & BMASK;
if (kind > OPMINI) if (kind > OPMINI)
kind = OPMINI; kind = OPMINI;
@ -115,7 +113,8 @@ oldline(lnp) register line_p lnp; {
oldcore((short * ) lnp, lsizetab[kind]); oldcore((short * ) lnp, lsizetab[kind]);
} }
arg_p newarg(kind) int kind; { arg_p newarg(int kind)
{
register arg_p ap; register arg_p ap;
ap = (arg_p) newcore(asizetab[kind]); ap = (arg_p) newcore(asizetab[kind]);
@ -123,12 +122,15 @@ arg_p newarg(kind) int kind; {
return (ap); return (ap);
} }
oldargs(ap) register arg_p ap; { void oldargs(register arg_p ap)
{
register arg_p next; register arg_p next;
while (ap != (arg_p) 0) { while (ap != (arg_p) 0)
{
next = ap->a_next; next = ap->a_next;
switch(ap->a_typ) { switch (ap->a_typ)
{
case ARGSTR: case ARGSTR:
oldargb(ap->a_a.a_string.ab_next); oldargb(ap->a_a.a_string.ab_next);
break; break;
@ -143,42 +145,46 @@ oldargs(ap) register arg_p ap; {
} }
} }
oldargb(abp) register argb_p abp; { void oldargb(register argb_p abp)
{
register argb_p next; register argb_p next;
while (abp != (argb_p) 0) { while (abp != (argb_p) 0)
{
next = abp->ab_next; next = abp->ab_next;
oldcore((short * ) abp, sizeof (argb_t)); oldcore((short * ) abp, sizeof (argb_t));
abp = next; abp = next;
} }
} }
reg_p newreg() { reg_p newreg(void)
{
return ((reg_p) newcore(sizeof(reg_t))); return ((reg_p) newcore(sizeof(reg_t)));
} }
oldreg(rp) reg_p rp; { void oldreg(reg_p rp)
{
oldcore((short * ) rp, sizeof(reg_t)); oldcore((short * ) rp, sizeof(reg_t));
} }
num_p newnum() { num_p newnum(void)
{
return ((num_p) newcore(sizeof(num_t))); return ((num_p) newcore(sizeof(num_t)));
} }
oldnum(lp) num_p lp; { void oldnum(num_p lp)
{
oldcore((short * ) lp, sizeof(num_t)); oldcore((short * ) lp, sizeof(num_t));
} }
offset *newrom() { offset *newrom(void)
{
return ((offset *) newcore(MAXROM*sizeof(offset))); return ((offset *) newcore(MAXROM*sizeof(offset)));
} }
sym_p newsym(len) int len; { sym_p newsym(int len)
{
/* /*
* sym_t includes a 2 character s_name at the end * sym_t includes a 2 character s_name at the end
* extend this structure with len-2 characters * extend this structure with len-2 characters
@ -186,8 +192,8 @@ sym_p newsym(len) int len; {
return ((sym_p) newcore(sizeof(sym_t) - 2 + len)); return ((sym_p) newcore(sizeof(sym_t) - 2 + len));
} }
argb_p newargb() { argb_p newargb(void)
{
return ((argb_p) newcore(sizeof(argb_t))); return ((argb_p) newcore(sizeof(argb_t)));
} }
@ -201,14 +207,16 @@ argb_p newargb() {
short *freelist[MAXSHORT]; short *freelist[MAXSHORT];
typedef struct coreblock { typedef struct coreblock
{
struct coreblock *co_next; struct coreblock *co_next;
short co_size; short co_size;
}core_t,*core_p; }core_t,*core_p;
#define SINC (sizeof(core_t)/sizeof(short)) #define SINC (sizeof(core_t)/sizeof(short))
#ifdef COREDEBUG #ifdef COREDEBUG
coreverbose() { coreverbose()
{
register size; register size;
register short *p; register short *p;
register sum; register sum;
@ -223,21 +231,27 @@ coreverbose() {
#ifdef SEPID #ifdef SEPID
compactcore() { compactcore()
{
register core_p corelist=0,tp,cl; register core_p corelist=0,tp,cl;
int size; int size;
#ifdef COREDEBUG #ifdef COREDEBUG
fprintf(stderr,"Almost out of core\n"); fprintf(stderr,"Almost out of core\n");
#endif #endif
for(size=SINC;size<MAXSHORT;size++) { for(size=SINC;size<MAXSHORT;size++)
while ((tp = (core_p) freelist[size]) != (core_p) 0) { {
while ((tp = (core_p) freelist[size]) != (core_p) 0)
{
freelist[size] = (short *) tp->co_next; freelist[size] = (short *) tp->co_next;
tp->co_size = size; tp->co_size = size;
if (corelist==0 || tp<corelist) { if (corelist==0 || tp<corelist)
{
tp->co_next = corelist; tp->co_next = corelist;
corelist = tp; corelist = tp;
} else { }
else
{
for(cl=corelist;cl->co_next != 0 && tp>cl->co_next; for(cl=corelist;cl->co_next != 0 && tp>cl->co_next;
cl = cl->co_next) cl = cl->co_next)
; ;
@ -246,21 +260,25 @@ compactcore() {
} }
} }
} }
while (corelist != 0) { while (corelist != 0)
{
while ((short *) corelist->co_next == while ((short *) corelist->co_next ==
(short *) corelist + corelist->co_size) { (short *) corelist + corelist->co_size)
{
corelist->co_size += corelist->co_next->co_size; corelist->co_size += corelist->co_next->co_size;
corelist->co_next = corelist->co_next->co_next; corelist->co_next = corelist->co_next->co_next;
} }
assert(corelist->co_next==0 || assert(corelist->co_next==0 ||
(short *) corelist->co_next > (short *) corelist->co_next >
(short *) corelist + corelist->co_size); (short *) corelist + corelist->co_size);
while (corelist->co_size >= MAXSHORT+SINC) { while (corelist->co_size >= MAXSHORT+SINC)
{
oldcore((short *) corelist + corelist->co_size-(MAXSHORT-1), oldcore((short *) corelist + corelist->co_size-(MAXSHORT-1),
sizeof(short)*(MAXSHORT-1)); sizeof(short)*(MAXSHORT-1));
corelist->co_size -= MAXSHORT; corelist->co_size -= MAXSHORT;
} }
if (corelist->co_size >= MAXSHORT) { if (corelist->co_size >= MAXSHORT)
{
oldcore((short *) corelist + corelist->co_size-SINC, oldcore((short *) corelist + corelist->co_size-SINC,
sizeof(short)*SINC); sizeof(short)*SINC);
corelist->co_size -= SINC; corelist->co_size -= SINC;
@ -271,7 +289,8 @@ compactcore() {
} }
} }
short *grabcore(size) int size; { short *grabcore(size) int size;
{
register short *p; register short *p;
register trysize; register trysize;
@ -283,9 +302,11 @@ short *grabcore(size) int size; {
*/ */
assert(size<2*MAXSHORT); assert(size<2*MAXSHORT);
for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) { for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2)
{
p = freelist[trysize/sizeof(short)]; p = freelist[trysize/sizeof(short)];
if ( p != (short *) 0) { if ( p != (short *) 0)
{
freelist[trysize/sizeof(short)] = *(short **) p; freelist[trysize/sizeof(short)] = *(short **) p;
oldcore(p+size/sizeof(short),trysize-size); oldcore(p+size/sizeof(short),trysize-size);
return(p); return(p);
@ -299,13 +320,16 @@ short *grabcore(size) int size; {
*/ */
compactcore(); compactcore();
if ((p=freelist[size/sizeof(short)]) != 0) { if ((p=freelist[size/sizeof(short)]) != 0)
{
freelist[size/sizeof(short)] = * (short **) p; freelist[size/sizeof(short)] = * (short **) p;
return(p); return(p);
} }
for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2) { for(trysize=2*MAXSHORT-2; trysize>size; trysize -= 2)
{
p = freelist[trysize/sizeof(short)]; p = freelist[trysize/sizeof(short)];
if ( p != (short *) 0) { if ( p != (short *) 0)
{
freelist[trysize/sizeof(short)] = *(short **) p; freelist[trysize/sizeof(short)] = *(short **) p;
oldcore(p+size/sizeof(short),trysize-size); oldcore(p+size/sizeof(short),trysize-size);
return(p); return(p);
@ -320,21 +344,25 @@ short *grabcore(size) int size; {
} }
#endif /* SEPID */ #endif /* SEPID */
short *newcore(size) int size; { short *newcore(size) int size;
{
register short *p,*q; register short *p,*q;
size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1); size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
if( size < 2*MAXSHORT ) { if( size < 2*MAXSHORT )
{
if ((p=freelist[size/sizeof(short)]) != (short *) 0) if ((p=freelist[size/sizeof(short)]) != (short *) 0)
freelist[size/sizeof(short)] = *(short **) p; freelist[size/sizeof(short)] = *(short **) p;
else { else
{
p = freshcore(size); p = freshcore(size);
#ifdef SEPID #ifdef SEPID
if (p == (short *) 0) if (p == (short *) 0)
p = grabcore(size); p = grabcore(size);
#endif #endif
} }
} else }
else
p = freshcore(size); p = freshcore(size);
if (p == 0) if (p == 0)
error("out of memory"); error("out of memory");
@ -350,7 +378,8 @@ short *newcore(size) int size; {
* you can use these as substitutes * you can use these as substitutes
*/ */
char *malloc(size) int size; { char *malloc(size) int size;
{
/* /*
* malloc(III) is called by stdio, * malloc(III) is called by stdio,
@ -360,12 +389,14 @@ char *malloc(size) int size; {
return( (char *) newcore(size)); return( (char *) newcore(size));
} }
free() { free()
{
} }
#endif #endif
oldcore(p,size) short *p; int size; { oldcore(p,size) short *p; int size;
{
#ifdef CORECHECK #ifdef CORECHECK
register short *cp; register short *cp;
#endif #endif
@ -382,7 +413,8 @@ oldcore(p,size) short *p; int size; {
short *ccur,*cend; short *ccur,*cend;
coreinit(p1,p2) short *p1,*p2; { coreinit(p1,p2) short *p1,*p2;
{
/* /*
* coreinit is called with the boundaries of a piece of * coreinit is called with the boundaries of a piece of
@ -393,12 +425,15 @@ coreinit(p1,p2) short *p1,*p2; {
cend = p2; cend = p2;
} }
short *freshcore(size) int size; { short *freshcore(size) int size;
{
register short *temp; register short *temp;
static int cchunk=CCHUNK; static int cchunk=CCHUNK;
while(&ccur[size/sizeof(short)] >= cend && cchunk>0) { while(&ccur[size/sizeof(short)] >= cend && cchunk>0)
do { {
do
{
temp = (short *) sbrk(cchunk*sizeof(short)); temp = (short *) sbrk(cchunk*sizeof(short));
if (temp == (short *) -1) if (temp == (short *) -1)
cchunk >>= 1; cchunk >>= 1;
@ -419,14 +454,15 @@ short *freshcore(size) int size; {
#else /* USEMALLOC */ #else /* USEMALLOC */
coreinit() { void coreinit(void)
{
/* /*
* Empty function, no initialization needed * Empty function, no initialization needed
*/ */
} }
short *myalloc(size) register size; { short *myalloc(register unsigned int size)
{
register short *p, *q; register short *p, *q;
p = (short *) malloc(size); p = (short *) malloc(size);

View file

@ -2,7 +2,10 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
*/ */
/* $Id$ */ #ifndef ALLOC_H_
#define ALLOC_H_
#include "types.h"
extern line_p newline(); extern line_p newline();
extern offset *newrom(); extern offset *newrom();
@ -12,9 +15,12 @@ extern arg_p newarg();
extern argb_p newargb(); extern argb_p newargb();
extern reg_p newreg(); extern reg_p newreg();
extern oldline(); void oldline(register line_p lnp);
extern oldloc(); void oldreg(reg_p rp);
extern oldreg(); void oldargs(register arg_p ap);
void oldargb(register argb_p abp);
void oldnum(num_p lp);
void coreinit(void);
#define USEMALLOC /* if defined malloc() and free() are used */ #define USEMALLOC /* if defined malloc() and free() are used */
@ -47,3 +53,5 @@ extern oldreg();
#define STACKROOM 1 /* 0 gives problems */ #define STACKROOM 1 /* 0 gives problems */
#endif /* USEMALLOC */ #endif /* USEMALLOC */
#endif /* ALLOC_H_ */

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h> #include <assert.h>
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
@ -15,13 +17,8 @@ static char rcsid[] = "$Id$";
#include <em_mnem.h> #include <em_mnem.h>
#include <em_mes.h> #include <em_mes.h>
#include "ext.h" #include "ext.h"
#include "getline.h"
/* #include "reg.h"
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#define local(x) ((((x)->s_flags&SYMKNOWN) == 0 && \ #define local(x) ((((x)->s_flags&SYMKNOWN) == 0 && \
((x)->s_flags &= ~ SYMGLOBAL)),\ ((x)->s_flags &= ~ SYMGLOBAL)),\
@ -40,9 +37,8 @@ short curfrag = 3; /* see also peephole.c */
offset rombuf[MAXROM]; offset rombuf[MAXROM];
int rc; int rc;
extern offset aoff(); void backward(void)
{
backward() {
register line_p lnp; register line_p lnp;
line_p next; line_p next;
register arg_p ap; register arg_p ap;
@ -52,9 +48,11 @@ backward() {
i = p = (line_p) 0; i = p = (line_p) 0;
curdtyp = 0; curdtyp = 0;
for (lnp = curpro.lastline; lnp != (line_p) 0; lnp = next) { for (lnp = curpro.lastline; lnp != (line_p) 0; lnp = next)
{
next = lnp->l_next; next = lnp->l_next;
switch(lnp->l_optyp) { switch (lnp->l_optyp)
{
case OPSYMBOL: case OPSYMBOL:
global(lnp->l_a.la_sp); global(lnp->l_a.la_sp);
break; break;
@ -66,8 +64,10 @@ backward() {
break; break;
case OPLIST: case OPLIST:
ap = lnp->l_a.la_arg; ap = lnp->l_a.la_arg;
while (ap != (arg_p) 0 ) { while (ap != (arg_p) 0)
switch(ap->a_typ) { {
switch (ap->a_typ)
{
case ARGSYM: case ARGSYM:
global(ap->a_a.a_sp); global(ap->a_a.a_sp);
break; break;
@ -84,7 +84,8 @@ backward() {
* for plain instructions nothing else is needed * for plain instructions nothing else is needed
*/ */
switch(lnp->l_instr&BMASK) { switch (lnp->l_instr & BMASK)
{
/* /*
* count all local occurences for register counts; * count all local occurences for register counts;
* op_lal is omitted and not by accident. * op_lal is omitted and not by accident.
@ -98,7 +99,8 @@ backward() {
case op_sil: case op_sil:
case op_stl: case op_stl:
case op_zrl: case op_zrl:
switch(lnp->l_optyp) { switch (lnp->l_optyp)
{
case OPNO: case OPNO:
case OPNUMLAB: case OPNUMLAB:
case OPSYMBOL: case OPSYMBOL:
@ -125,7 +127,8 @@ backward() {
case ps_sym: case ps_sym:
sp = lnp->l_a.la_sp; sp = lnp->l_a.la_sp;
local(sp); local(sp);
if (curdtyp == DTYPROM && goodrom) { if (curdtyp == DTYPROM && goodrom)
{
sp->s_rom = newrom(); sp->s_rom = newrom();
for (n = 0; n < rc; n++) for (n = 0; n < rc; n++)
sp->s_rom[n] = rombuf[n]; sp->s_rom[n] = rombuf[n];
@ -141,32 +144,38 @@ backward() {
curfrag++; curfrag++;
break; break;
case ps_con: case ps_con:
if (curdtyp != DTYPCON) { if (curdtyp != DTYPCON)
{
curdtyp = DTYPCON; curdtyp = DTYPCON;
curfrag++; curfrag++;
} }
break; break;
case ps_rom: case ps_rom:
if (curdtyp != DTYPROM) { if (curdtyp != DTYPROM)
{
curdtyp = DTYPROM; curdtyp = DTYPROM;
curfrag++; curfrag++;
} }
ap = lnp->l_a.la_arg; ap = lnp->l_a.la_arg;
rc = 0; rc = 0;
while (ap != (arg_p) 0 && rc < MAXROM) { while (ap != (arg_p) 0 && rc < MAXROM)
if (ap->a_typ == ARGOFF) { {
if (ap->a_typ == ARGOFF)
{
rombuf[rc++] = ap->a_a.a_offset; rombuf[rc++] = ap->a_a.a_offset;
ap = ap->a_next; ap = ap->a_next;
} else }
else
ap = (arg_p) 0; ap = (arg_p) 0;
} }
goodrom = (rc >= 2); goodrom = (rc >= 2);
break; break;
case ps_mes: case ps_mes:
if (prodepth != 0 && if (prodepth != 0
((int) aoff(lnp->l_a.la_arg, 0) == ms_std || && ((int) aoff(lnp->l_a.la_arg, 0) == ms_std
(int) aoff(lnp->l_a.la_arg, 0) == ms_stb || || (int) aoff(lnp->l_a.la_arg, 0) == ms_stb
(int) aoff(lnp->l_a.la_arg, 0) == ms_ego)) { || (int) aoff(lnp->l_a.la_arg, 0) == ms_ego))
{
lnp->l_next = i; lnp->l_next = i;
i = lnp; i = lnp;
continue; continue;
@ -186,5 +195,7 @@ backward() {
} }
if (prodepth != 0) if (prodepth != 0)
local(curpro.symbol); local(curpro.symbol);
instrs = i; pseudos = p; curpro.lastline = (line_p) 0; instrs = i;
pseudos = p;
curpro.lastline = (line_p) 0;
} }

View file

@ -11,9 +11,9 @@ flex {
} }
local headers = { local headers = {
"./alloc.h", "./ext.h", "./line.h", "./lookup.h", "./optim.h", "./alloc.h", "./ext.h", "./getline.h", "./line.h", "./lookup.h", "./optim.h",
"./param.h", "./pattern.h", "./pop_push.h", "./proinf.h", "./param.h", "./pattern.h", "./pop_push.h", "./proinf.h","./putline.h",
"./tes.h", "./types.h", "./reg.h","./tes.h", "./types.h","./util.h"
} }
cprogram { cprogram {

View file

@ -1,30 +1,25 @@
#ifndef NORCSID
static char rcsid[] = "$Id$";
#endif
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include "param.h"
#include "types.h"
#include <em_pseu.h>
#include <em_spec.h>
#include <em_mes.h>
#include "lookup.h"
#include "ext.h"
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
* *
* Author: Hans van Staveren * Author: Hans van Staveren
*/ */
#include <assert.h>
#include <stdio.h>
#include "param.h"
#include "types.h"
#include <em_pseu.h>
#include <em_spec.h>
#include <em_mes.h>
#include "lookup.h"
#include "putline.h"
#include "util.h"
#include "ext.h"
void cleanup(void)
void {
cleanup() {
FILE *infile; FILE *infile;
register c; register int c;
register sym_p *spp, sp; register sym_p *spp, sp;
for (spp = symhash; spp < &symhash[NSYMHASH]; spp++) for (spp = symhash; spp < &symhash[NSYMHASH]; spp++)
@ -36,15 +31,17 @@ cleanup() {
c = fclose(outfile); c = fclose(outfile);
assert(c != EOF); assert(c != EOF);
outfile = stdout; outfile = stdout;
infile = fopen(template,"r"); infile = fopen(tempname, "r");
if (infile == NULL) if (infile == NULL)
error("temp file disappeared"); error("temp file disappeared");
outshort(sp_magic); outshort(sp_magic);
/* Attempt to first output the word_size message */ /* Attempt to first output the word_size message */
while ((c = getc(infile)) != sp_cend && c != EOF) { while ((c = getc(infile)) != sp_cend && c != EOF)
{
putc(c, outfile); putc(c, outfile);
} }
if (c == sp_cend) putc(c, outfile); if (c == sp_cend)
putc(c, outfile);
outinst(ps_mes); outinst(ps_mes);
outint(ms_ext); outint(ms_ext);
for (spp = symhash; spp < &symhash[NSYMHASH]; spp++) for (spp = symhash; spp < &symhash[NSYMHASH]; spp++)
@ -56,6 +53,6 @@ cleanup() {
putc(c, outfile); putc(c, outfile);
c = fclose(infile); c = fclose(infile);
assert(c != EOF); assert(c != EOF);
c=unlink(template); c = remove(tempname);
assert(c == 0); assert(c == 0);
} }

View file

@ -3,7 +3,7 @@
.SH NAME .SH NAME
em_opt \- EM peephole optimizer em_opt \- EM peephole optimizer
.SH SYNOPSIS .SH SYNOPSIS
.B ~em/lib.bin/em_opt .B em_opt
[\-Ln] [\-m[l]<num>] [ argument ] [\-Ln] [\-m[l]<num>] [ argument ]
.SH DESCRIPTION .SH DESCRIPTION
Em_opt reads a compact EM-program, argument or standard input, Em_opt reads a compact EM-program, argument or standard input,

View file

@ -16,7 +16,7 @@ extern bool repl_longmuls;
extern byte em_flag[]; extern byte em_flag[];
extern line_p instrs,pseudos; extern line_p instrs,pseudos;
extern FILE *outfile; extern FILE *outfile;
extern char template[]; extern char tempname[];
extern offset wordsize; extern offset wordsize;
extern offset pointersize; extern offset pointersize;
extern char *progname; extern char *progname;

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
#include "tes.h" #include "tes.h"
@ -14,37 +16,38 @@ static char rcsid[] = "$Id$";
#include "optim.h" #include "optim.h"
#include "ext.h" #include "ext.h"
/* /* Forward declarations */
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. static void reach(register line_p);
* See the copyright notice in the ACK home directory, in the file "Copyright". static void findreach(void);
* static void cleaninstrs(void);
* Author: Hans van Staveren
*/
void reach();
flow() {
void flow(void)
{
findreach(); /* determine reachable labels */ findreach(); /* determine reachable labels */
cleaninstrs(); /* throw away unreachable code */ cleaninstrs(); /* throw away unreachable code */
} }
findreach() { static void findreach(void)
{
register num_p *npp, np; register num_p *npp, np;
reach(instrs); reach(instrs);
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np = np->n_next) for (np = *npp; np != (num_p) 0; np = np->n_next)
if (np->n_flags&NUMDATA) { if (np->n_flags & NUMDATA)
{
np->n_repl->n_flags |= NUMREACH; np->n_repl->n_flags |= NUMREACH;
np->n_repl->n_jumps++; np->n_repl->n_jumps++;
if (!(np->n_flags&NUMSCAN)) { if (!(np->n_flags & NUMSCAN))
{
np->n_flags |= NUMSCAN; np->n_flags |= NUMSCAN;
if (np->n_line) { if (np->n_line)
{
reach(np->n_line->l_next); reach(np->n_line->l_next);
continue; continue;
} }
if (!(np->n_repl->n_flags&NUMSCAN)) { if (!(np->n_repl->n_flags & NUMSCAN))
{
np->n_repl->n_flags |= NUMSCAN; np->n_repl->n_flags |= NUMSCAN;
if (np->n_repl->n_line) if (np->n_repl->n_line)
reach(np->n_repl->n_line->l_next); reach(np->n_repl->n_line->l_next);
@ -53,12 +56,14 @@ findreach() {
} }
} }
void static void reach(register line_p lnp)
reach(lnp) register line_p lnp; { {
register num_p np; register num_p np;
for (;lnp != (line_p) 0; lnp = lnp->l_next) { for (; lnp != (line_p) 0; lnp = lnp->l_next)
if(lnp->l_optyp == OPNUMLAB) { {
if (lnp->l_optyp == OPNUMLAB)
{
/* /*
* Branch instruction or label * Branch instruction or label
*/ */
@ -66,14 +71,17 @@ reach(lnp) register line_p lnp; {
if ((lnp->l_instr & BMASK) != op_lab) if ((lnp->l_instr & BMASK) != op_lab)
lnp->l_a.la_np = np = np->n_repl; lnp->l_a.la_np = np = np->n_repl;
np->n_flags |= NUMREACH; np->n_flags |= NUMREACH;
if (!(np->n_flags&NUMSCAN)) { if (!(np->n_flags & NUMSCAN))
{
np->n_flags |= NUMSCAN; np->n_flags |= NUMSCAN;
if (np->n_line) if (np->n_line)
reach(np->n_line->l_next); reach(np->n_line->l_next);
else { else
{
np = np->n_repl; np = np->n_repl;
np->n_flags |= NUMREACH; np->n_flags |= NUMREACH;
if (!(np->n_flags & NUMSCAN)) { if (!(np->n_flags & NUMSCAN))
{
np->n_flags |= NUMSCAN; np->n_flags |= NUMSCAN;
if (np->n_line) if (np->n_line)
reach(np->n_line->l_next); reach(np->n_line->l_next);
@ -85,26 +93,33 @@ reach(lnp) register line_p lnp; {
else else
np->n_jumps++; np->n_jumps++;
} }
if ((lnp->l_instr & BMASK) > sp_lmnem) continue; if ((lnp->l_instr & BMASK) > sp_lmnem)
continue;
if ((em_flag[(lnp->l_instr & BMASK) - sp_fmnem] & EM_FLO) == FLO_T) if ((em_flag[(lnp->l_instr & BMASK) - sp_fmnem] & EM_FLO) == FLO_T)
return; return;
} }
} }
cleaninstrs() { static void cleaninstrs(void)
{
register line_p *lpp, lp, *lastbra; register line_p *lpp, lp, *lastbra;
bool reachable, superfluous; bool reachable, superfluous;
int instr; int instr;
lpp = &instrs; lastbra = (line_p *) 0; reachable = TRUE; lpp = &instrs;
while ((lp = *lpp) != (line_p) 0) { lastbra = (line_p *) 0;
instr = lp->l_instr&BMASK;
if (instr == op_lab) {
if ((lp->l_a.la_np->n_flags&NUMREACH) != 0) {
reachable = TRUE; reachable = TRUE;
if (lastbra != (line_p *) 0 while ((lp = *lpp) != (line_p) 0)
&& (*lastbra)->l_next == lp {
&& (*lastbra)->l_a.la_np->n_repl==lp->l_a.la_np) { instr = lp->l_instr & BMASK;
if (instr == op_lab)
{
if ((lp->l_a.la_np->n_flags & NUMREACH) != 0)
{
reachable = TRUE;
if (lastbra != (line_p *) 0 && (*lastbra)->l_next == lp
&& (*lastbra)->l_a.la_np->n_repl == lp->l_a.la_np)
{
oldline(*lastbra); oldline(*lastbra);
OPTIM(O_BRALAB); OPTIM(O_BRALAB);
lpp = lastbra; lpp = lastbra;
@ -113,19 +128,23 @@ cleaninstrs() {
lp->l_a.la_np->n_jumps--; lp->l_a.la_np->n_jumps--;
} }
} }
if ( lp->l_a.la_np->n_repl != lp->l_a.la_np || if (lp->l_a.la_np->n_repl != lp->l_a.la_np
((lp->l_a.la_np->n_flags&NUMDATA)==0 && || ((lp->l_a.la_np->n_flags & NUMDATA) == 0
lp->l_a.la_np->n_jumps == 0)) && lp->l_a.la_np->n_jumps == 0))
superfluous = TRUE; superfluous = TRUE;
else else
superfluous = FALSE; superfluous = FALSE;
} else }
else
superfluous = FALSE; superfluous = FALSE;
if ( (!reachable) || superfluous) { if ((!reachable) || superfluous)
if (instr == op_lab) { {
if (instr == op_lab)
{
lp->l_a.la_np->n_line = 0; lp->l_a.la_np->n_line = 0;
} }
else if (instr > sp_lmnem) { else if (instr > sp_lmnem)
{
/* leave pseudo's */ /* leave pseudo's */
lpp = &lp->l_next; lpp = &lp->l_next;
continue; continue;
@ -134,9 +153,12 @@ cleaninstrs() {
oldline(*lpp); oldline(*lpp);
OPTIM(O_UNREACH); OPTIM(O_UNREACH);
*lpp = lp; *lpp = lp;
} else { }
if ( instr <= sp_lmnem && else
(em_flag[instr-sp_fmnem]&EM_FLO)==FLO_T) { {
if (instr <= sp_lmnem
&& (em_flag[instr - sp_fmnem] & EM_FLO) == FLO_T)
{
reachable = FALSE; reachable = FALSE;
if ((lp->l_instr & BMASK) == op_bra) if ((lp->l_instr & BMASK) == op_bra)
lastbra = lpp; lastbra = lpp;

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "param.h" #include "param.h"
@ -16,14 +18,9 @@ static char rcsid[] = "$Id$";
#include <em_flag.h> #include <em_flag.h>
#include <em_mes.h> #include <em_mes.h>
#include "ext.h" #include "ext.h"
#include "reg.h"
/* #include "getline.h"
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. #include "util.h"
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
static short tabval; /* temp store for shorts */ static short tabval; /* temp store for shorts */
static offset tabval2; /* temp store for offsets */ static offset tabval2; /* temp store for offsets */
@ -44,17 +41,32 @@ static char string[IDL+1]; /* temp store for names */
#define readbyte getchar #define readbyte getchar
short readshort() { /* Other external declarations */
extern void process(void);
/* Forward declarations */
static int table2(void);
static void tstinpro(void)
{
if (prodepth == 0)
error("This is not allowed outside a procedure");
}
short readshort(void)
{
register int l_byte, h_byte; register int l_byte, h_byte;
l_byte = readbyte(); l_byte = readbyte();
h_byte = readbyte(); h_byte = readbyte();
if ( h_byte>=128 ) h_byte -= 256 ; if (h_byte >= 128)
h_byte -= 256;
return l_byte | (h_byte * 256); return l_byte | (h_byte * 256);
} }
#ifdef LONGOFF #ifdef LONGOFF
offset readoffset() { static offset readoffset(void)
{
register long l; register long l;
register int h_byte; register int h_byte;
@ -62,34 +74,38 @@ offset readoffset() {
l |= ((unsigned) readbyte()) * 256; l |= ((unsigned) readbyte()) * 256;
l |= readbyte() * 256L * 256L; l |= readbyte() * 256L * 256L;
h_byte = readbyte(); h_byte = readbyte();
if ( h_byte>=128 ) h_byte -= 256 ; if (h_byte >= 128)
h_byte -= 256;
return l | (h_byte * 256L * 256 * 256L); return l | (h_byte * 256L * 256 * 256L);
} }
#endif #endif
draininput() { static void draininput(void)
{
/* /*
* called when MES ERR is encountered. * called when MES ERR is encountered.
* Drain input in case it is a pipe. * Drain input in case it is a pipe.
*/ */
while (getchar() != EOF) while (getchar() != EOF)
; ;
} }
short getint() { static short getint(void)
{
switch(table2()) { switch (table2())
default: error("int expected"); {
default:
error("int expected");
case CSTX1: case CSTX1:
return (tabval); return (tabval);
} }
} }
sym_p getsym(status) int status; { static sym_p getsym(int status)
{
switch(table2()) { switch (table2())
{
default: default:
error("symbol expected"); error("symbol expected");
case DLBX: case DLBX:
@ -99,10 +115,12 @@ sym_p getsym(status) int status; {
} }
} }
offset getoff() { static offset getoff(void)
{
switch (table2()) { switch (table2())
default: error("offset expected"); {
default:
error("offset expected");
case CSTX1: case CSTX1:
return ((offset) tabval); return ((offset) tabval);
#ifdef LONGOFF #ifdef LONGOFF
@ -112,18 +130,20 @@ offset getoff() {
} }
} }
make_string(n) int n; { static void make_string(int n)
{
sprintf(string, ".%u", n); sprintf(string, ".%u", n);
} }
inident() { static void inident(void)
register n; {
register int n;
register char *p = string; register char *p = string;
register c; register int c;
n = getint(); n = getint();
while (n--) { while (n--)
{
c = readbyte(); c = readbyte();
if (p < &string[IDL]) if (p < &string[IDL])
*p++ = c; *p++ = c;
@ -131,188 +151,110 @@ inident() {
*p++ = 0; *p++ = 0;
} }
int table3(n) int n; { static int table3(int n)
{
switch (n) { switch (n)
case sp_ilb1: tabval = readbyte(); return(ILBX); {
case sp_ilb2: tabval = readshort(); return(ILBX); case sp_ilb1:
case sp_dlb1: make_string(readbyte()); return(DLBX); tabval = readbyte();
case sp_dlb2: make_string(readshort()); return(DLBX); return (ILBX);
case sp_dnam: inident(); return(DLBX); case sp_ilb2:
case sp_pnam: inident(); return(n); tabval = readshort();
case sp_cst2: tabval = readshort(); return(CSTX1); return (ILBX);
case sp_dlb1:
make_string(readbyte());
return (DLBX);
case sp_dlb2:
make_string(readshort());
return (DLBX);
case sp_dnam:
inident();
return (DLBX);
case sp_pnam:
inident();
return (n);
case sp_cst2:
tabval = readshort();
return (CSTX1);
#ifdef LONGOFF #ifdef LONGOFF
case sp_cst4: tabval2 = readoffset(); return(CSTX2); case sp_cst4:
tabval2 = readoffset();
return (CSTX2);
#endif #endif
case sp_doff: if (table2()!=DLBX) error("symbol expected"); case sp_doff:
switch(table2()) { if (table2() != DLBX)
default: error("offset expected"); error("symbol expected");
case CSTX1: return(VALX1); switch (table2())
{
default:
error("offset expected");
case CSTX1:
return (VALX1);
#ifdef LONGOFF #ifdef LONGOFF
case CSTX2: return(VALX2); case CSTX2:
return (VALX2);
#endif #endif
} }
default: return(n); default:
return (n);
} }
} }
int table1() { static int table1(void)
register n; {
register int n;
n = readbyte(); n = readbyte();
if (n == EOF) if (n == EOF)
return (ATEOF); return (ATEOF);
if ((n <= sp_lmnem) && (n >= sp_fmnem)) { if ((n <= sp_lmnem) && (n >= sp_fmnem))
{
tabval = n; tabval = n;
return (INST); return (INST);
} }
if ((n <= sp_lpseu) && (n >= sp_fpseu)) { if ((n <= sp_lpseu) && (n >= sp_fpseu))
{
tabval = n; tabval = n;
return (PSEU); return (PSEU);
} }
if ((n < sp_filb0 + sp_nilb0) && (n >= sp_filb0)) { if ((n < sp_filb0 + sp_nilb0) && (n >= sp_filb0))
{
tabval = n - sp_filb0; tabval = n - sp_filb0;
return (ILBX); return (ILBX);
} }
return (table3(n)); return (table3(n));
} }
int table2() { static int table2(void)
register n; {
register int n;
n = readbyte(); n = readbyte();
if ((n < sp_fcst0 + sp_ncst0) && (n >= sp_fcst0)) { if ((n < sp_fcst0 + sp_ncst0) && (n >= sp_fcst0))
{
tabval = n - sp_zcst0; tabval = n - sp_zcst0;
return (CSTX1); return (CSTX1);
} }
return (table3(n)); return (table3(n));
} }
void static void argstring(offset length, register argb_p abp)
getlines() { {
register line_p lnp; while (length--)
register instr; {
for(;;) {
linecount++;
switch(table1()) {
default:
error("unknown instruction byte");
/* NOTREACHED */
case ATEOF:
if (prodepth!=0)
error("procedure unterminated at eof");
process();
return;
case INST:
tstinpro();
instr = tabval;
break;
case DLBX:
lnp = newline(OPSYMBOL);
lnp->l_instr = ps_sym;
lnp->l_a.la_sp= symlookup(string,DEFINING,0);
lnp->l_next = curpro.lastline;
curpro.lastline = lnp;
continue;
case ILBX:
tstinpro();
lnp = newline(OPNUMLAB);
lnp->l_instr = op_lab;
lnp->l_a.la_np = numlookup((unsigned) tabval);
if (lnp->l_a.la_np->n_line != (line_p) 0)
error("label %u multiple defined",(unsigned) tabval);
lnp->l_a.la_np->n_line = lnp;
lnp->l_next = curpro.lastline;
curpro.lastline = lnp;
continue;
case PSEU:
if(inpseudo(tabval))
return;
continue;
}
/*
* Now we have an instruction number in instr
* There might be an operand, look for it
*/
if ((em_flag[instr-sp_fmnem]&EM_PAR)==PAR_NO) {
lnp = newline(OPNO);
} else switch(table2()) {
default:
error("unknown offset byte");
case sp_cend:
lnp = newline(OPNO);
break;
case CSTX1:
if ((em_flag[instr-sp_fmnem]&EM_PAR)!= PAR_B) {
if (CANMINI(tabval))
lnp = newline(tabval+Z_OPMINI);
else {
lnp = newline(OPSHORT);
lnp->l_a.la_short = tabval;
}
} else {
lnp = newline(OPNUMLAB);
lnp->l_a.la_np = numlookup((unsigned) tabval);
}
break;
#ifdef LONGOFF
case CSTX2:
lnp = newline(OPOFFSET);
lnp->l_a.la_offset = tabval2;
break;
#endif
case ILBX:
tstinpro();
lnp = newline(OPNUMLAB);
lnp->l_a.la_np = numlookup((unsigned) tabval);
break;
case DLBX:
lnp = newline(OPSYMBOL);
lnp->l_a.la_sp = symlookup(string,OCCURRING,0);
break;
case sp_pnam:
lnp = newline(OPSYMBOL);
lnp->l_a.la_sp = symlookup(string,OCCURRING,SYMPRO);
break;
case VALX1:
lnp = newline(OPSVAL);
lnp->l_a.la_sval.lasv_sp = symlookup(string,OCCURRING,0);
lnp->l_a.la_sval.lasv_short = tabval;
break;
#ifdef LONGOFF
case VALX2:
lnp = newline(OPLVAL);
lnp->l_a.la_lval.lalv_sp = symlookup(string,OCCURRING,0);
lnp->l_a.la_lval.lalv_offset = tabval2;
break;
#endif
}
lnp->l_instr = instr;
lnp->l_next = curpro.lastline;
curpro.lastline = lnp;
}
}
argstring(length,abp) offset length; register argb_p abp; {
while (length--) {
if (abp->ab_index == NARGBYTES) if (abp->ab_index == NARGBYTES)
abp = abp->ab_next = newargb(); abp = abp->ab_next = newargb();
abp->ab_contents[abp->ab_index++] = readbyte(); abp->ab_contents[abp->ab_index++] = readbyte();
} }
} }
line_p arglist(n) int n; { static line_p arglist(int n)
{
line_p lnp; line_p lnp;
register arg_p ap, *app; register arg_p ap, *app;
bool moretocome; bool moretocome;
offset length; offset length;
/* /*
* creates an arglist with n elements * creates an arglist with n elements
* if n == 0 the arglist is variable and terminated by sp_cend * if n == 0 the arglist is variable and terminated by sp_cend
@ -321,8 +263,10 @@ line_p arglist(n) int n; {
lnp = newline(OPLIST); lnp = newline(OPLIST);
app = &lnp->l_a.la_arg; app = &lnp->l_a.la_arg;
moretocome = TRUE; moretocome = TRUE;
do { do
switch(table2()) { {
switch (table2())
{
default: default:
error("unknown byte in arglist"); error("unknown byte in arglist");
case CSTX1: case CSTX1:
@ -371,8 +315,7 @@ line_p arglist(n) int n; {
goto casecon; goto casecon;
case sp_fcon: case sp_fcon:
*app = ap = newarg(ARGFCN); *app = ap = newarg(ARGFCN);
casecon: casecon: length = getint();
length = getint();
ap->a_a.a_con.ac_length = (short) length; ap->a_a.a_con.ac_length = (short) length;
argstring(getoff(), &ap->a_a.a_con.ac_con); argstring(getoff(), &ap->a_a.a_con.ac_con);
app = &ap->a_next; app = &ap->a_next;
@ -386,9 +329,11 @@ line_p arglist(n) int n; {
return (lnp); return (lnp);
} }
offset aoff(ap,n) register arg_p ap; { offset aoff(register arg_p ap, int n)
{
while (n>0) { while (n > 0)
{
if (ap != (arg_p) 0) if (ap != (arg_p) 0)
ap = ap->a_next; ap = ap->a_next;
n--; n--;
@ -400,20 +345,23 @@ offset aoff(ap,n) register arg_p ap; {
return (ap->a_a.a_offset); return (ap->a_a.a_offset);
} }
int inpseudo(n) short n; { static int inpseudo(short n)
{
register line_p lnp, head, tail; register line_p lnp, head, tail;
short n1, n2; short n1, n2;
proinf savearea; proinf savearea;
#ifdef PSEUBETWEEN #ifdef PSEUBETWEEN
static int pcount = 0; static int pcount = 0;
if (pcount++ >= PSEUBETWEEN && prodepth==0) { if (pcount++ >= PSEUBETWEEN && prodepth == 0)
{
process(); process();
pcount = 0; pcount = 0;
} }
#endif #endif
switch(n) { switch (n)
{
default: default:
error("unknown pseudo"); error("unknown pseudo");
case ps_bss: case ps_bss:
@ -432,12 +380,16 @@ int inpseudo(n) short n; {
lnp->l_a.la_sp = getsym(NOTHING); lnp->l_a.la_sp = getsym(NOTHING);
break; break;
case ps_exc: case ps_exc:
n1 = getint(); n2 = getint(); n1 = getint();
if (n1 != 0 && n2 != 0) { n2 = getint();
if (n1 != 0 && n2 != 0)
{
tail = curpro.lastline; tail = curpro.lastline;
while (--n2) tail = tail->l_next; while (--n2)
tail = tail->l_next;
head = tail; head = tail;
while (n1--) head = head->l_next; while (n1--)
head = head->l_next;
lnp = tail->l_next; lnp = tail->l_next;
tail->l_next = head->l_next; tail->l_next = head->l_next;
head->l_next = curpro.lastline; head->l_next = curpro.lastline;
@ -447,11 +399,14 @@ int inpseudo(n) short n; {
break; break;
case ps_mes: case ps_mes:
lnp = arglist(0); lnp = arglist(0);
switch((int) aoff(lnp->l_a.la_arg,0)) { switch ((int) aoff(lnp->l_a.la_arg, 0))
{
case ms_err: case ms_err:
draininput(); exit(-1); draininput();
exit(-1);
case ms_opt: case ms_opt:
nflag = TRUE; break; nflag = TRUE;
break;
case ms_emx: case ms_emx:
wordsize = aoff(lnp->l_a.la_arg, 1); wordsize = aoff(lnp->l_a.la_arg, 1);
pointersize = aoff(lnp->l_a.la_arg, 2); pointersize = aoff(lnp->l_a.la_arg, 2);
@ -484,7 +439,8 @@ int inpseudo(n) short n; {
else else
process(); process();
curpro.symbol = getsym(DEFINING); curpro.symbol = getsym(DEFINING);
switch(table2()) { switch (table2())
{
case sp_cend: case sp_cend:
curpro.localbytes = (offset) -1; curpro.localbytes = (offset) -1;
break; break;
@ -498,8 +454,9 @@ int inpseudo(n) short n; {
} }
prodepth++; prodepth++;
curpro.gtoproc = 0; curpro.gtoproc = 0;
if (prodepth>1) { if (prodepth > 1)
register i; {
register int i;
curpro.lastline = (line_p) 0; curpro.lastline = (line_p) 0;
curpro.freg = (reg_p) 0; curpro.freg = (reg_p) 0;
@ -513,7 +470,8 @@ int inpseudo(n) short n; {
case ps_end: case ps_end:
if (prodepth == 0) if (prodepth == 0)
error("END misplaced"); error("END misplaced");
switch(table2()) { switch (table2())
{
case sp_cend: case sp_cend:
if (curpro.localbytes == (offset) -1) if (curpro.localbytes == (offset) -1)
error("bytes for locals still unknown"); error("bytes for locals still unknown");
@ -521,20 +479,23 @@ int inpseudo(n) short n; {
case CSTX1: case CSTX1:
tabval2 = (offset) tabval; tabval2 = (offset) tabval;
case CSTX2: case CSTX2:
if (curpro.localbytes != (offset) -1 && curpro.localbytes != tabval2) if (curpro.localbytes != (offset) -1
&& curpro.localbytes != tabval2)
error("inconsistency in number of bytes for locals"); error("inconsistency in number of bytes for locals");
curpro.localbytes = tabval2; curpro.localbytes = tabval2;
break; break;
} }
process(); process();
curpro.symbol = (sym_p) 0; curpro.symbol = (sym_p) 0;
if (prodepth==1) { if (prodepth == 1)
{
prodepth = 0; prodepth = 0;
#ifdef PSEUBETWEEN #ifdef PSEUBETWEEN
pcount = 0; pcount = 0;
#endif #endif
return (0); return (0);
} else }
else
return (1); return (1);
} }
lnp->l_instr = n; lnp->l_instr = n;
@ -543,8 +504,122 @@ int inpseudo(n) short n; {
return (0); return (0);
} }
tstinpro() { void getlines(void)
{
register line_p lnp;
register int instr;
if (prodepth==0) for (;;)
error("This is not allowed outside a procedure"); {
linecount++;
switch (table1())
{
default:
error("unknown instruction byte");
/* NOTREACHED */
case ATEOF:
if (prodepth != 0)
error("procedure unterminated at eof");
process();
return;
case INST:
tstinpro();
instr = tabval;
break;
case DLBX:
lnp = newline(OPSYMBOL);
lnp->l_instr = ps_sym;
lnp->l_a.la_sp = symlookup(string, DEFINING, 0);
lnp->l_next = curpro.lastline;
curpro.lastline = lnp;
continue;
case ILBX:
tstinpro();
lnp = newline(OPNUMLAB);
lnp->l_instr = op_lab;
lnp->l_a.la_np = numlookup((unsigned) tabval);
if (lnp->l_a.la_np->n_line != (line_p) 0)
error("label %u multiple defined", (unsigned) tabval);
lnp->l_a.la_np->n_line = lnp;
lnp->l_next = curpro.lastline;
curpro.lastline = lnp;
continue;
case PSEU:
if (inpseudo(tabval))
return;
continue;
} }
/*
* Now we have an instruction number in instr
* There might be an operand, look for it
*/
if ((em_flag[instr - sp_fmnem] & EM_PAR) == PAR_NO)
{
lnp = newline(OPNO);
}
else
switch (table2())
{
default:
error("unknown offset byte");
case sp_cend:
lnp = newline(OPNO);
break;
case CSTX1:
if ((em_flag[instr - sp_fmnem] & EM_PAR) != PAR_B)
{
if (CANMINI(tabval))
lnp = newline(tabval + Z_OPMINI);
else
{
lnp = newline(OPSHORT);
lnp->l_a.la_short = tabval;
}
}
else
{
lnp = newline(OPNUMLAB);
lnp->l_a.la_np = numlookup((unsigned) tabval);
}
break;
#ifdef LONGOFF
case CSTX2:
lnp = newline(OPOFFSET);
lnp->l_a.la_offset = tabval2;
break;
#endif
case ILBX:
tstinpro();
lnp = newline(OPNUMLAB);
lnp->l_a.la_np = numlookup((unsigned) tabval);
break;
case DLBX:
lnp = newline(OPSYMBOL);
lnp->l_a.la_sp = symlookup(string, OCCURRING, 0);
break;
case sp_pnam:
lnp = newline(OPSYMBOL);
lnp->l_a.la_sp = symlookup(string, OCCURRING, SYMPRO);
break;
case VALX1:
lnp = newline(OPSVAL);
lnp->l_a.la_sval.lasv_sp = symlookup(string, OCCURRING, 0);
lnp->l_a.la_sval.lasv_short = tabval;
break;
#ifdef LONGOFF
case VALX2:
lnp = newline(OPLVAL);
lnp->l_a.la_lval.lalv_sp = symlookup(string, OCCURRING, 0);
lnp->l_a.la_lval.lalv_offset = tabval2;
break;
#endif
}
lnp->l_instr = instr;
lnp->l_next = curpro.lastline;
curpro.lastline = lnp;
}
}

17
util/opt/getline.h Normal file
View file

@ -0,0 +1,17 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-04-07
*
*/
#ifndef GETLINE_H_
#define GETLINE_H_
#include "types.h"
void getlines(void);
offset aoff(register arg_p ap, int n);
short readshort(void);
#endif /* GETLINE_H_ */

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "param.h" #include "param.h"
@ -10,15 +12,10 @@ static char rcsid[] = "$Id$";
#include "lookup.h" #include "lookup.h"
#include "alloc.h" #include "alloc.h"
#include "proinf.h" #include "proinf.h"
#include "util.h"
/* unsigned hash(char *string)
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. {
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
unsigned hash(string) char *string; {
register char *p; register char *p;
register unsigned i, sum; register unsigned i, sum;
@ -27,24 +24,28 @@ unsigned hash(string) char *string; {
return (sum); return (sum);
} }
sym_p symlookup(name,status,flags) char *name; int status,flags; { sym_p symlookup(char *name, int status, int flags)
{
register sym_p *spp, sp; register sym_p *spp, sp;
register i; register int i;
static short genfrag = 32767; static short genfrag = 32767;
spp = &symhash[hash(name) % NSYMHASH]; spp = &symhash[hash(name) % NSYMHASH];
while (*spp != (sym_p) 0) while (*spp != (sym_p) 0)
if (strncmp((*spp)->s_name,name,IDL)==0) { if (strncmp((*spp)->s_name, name, IDL) == 0)
{
sp = *spp; sp = *spp;
if ((sp->s_flags ^ flags) & SYMPRO) if ((sp->s_flags ^ flags) & SYMPRO)
error("%s is both proc and datalabel", name); error("%s is both proc and datalabel", name);
if (status == DEFINING) { if (status == DEFINING)
{
if (sp->s_flags & SYMDEF) if (sp->s_flags & SYMDEF)
error("redefined symbol %s", name); error("redefined symbol %s", name);
sp->s_flags |= SYMDEF; sp->s_flags |= SYMDEF;
} }
return (sp); return (sp);
} else }
else
spp = &(*spp)->s_next; spp = &(*spp)->s_next;
/* /*
@ -65,7 +66,8 @@ sym_p symlookup(name,status,flags) char *name; int status,flags; {
return (sp); return (sp);
} }
num_p numlookup(number) unsigned number; { num_p numlookup(unsigned number)
{
register num_p *npp, np; register num_p *npp, np;
npp = &curpro.numhash[number % NNUMHASH]; npp = &curpro.numhash[number % NNUMHASH];

View file

@ -2,7 +2,10 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
*/ */
/* $Id$ */ #ifndef LOOKUP_H_
#define LOOKUP_H_
#include "types.h"
#define IDL 100 #define IDL 100
@ -28,3 +31,14 @@ extern sym_p symhash[NSYMHASH],symlookup();
#define OCCURRING 0 #define OCCURRING 0
#define DEFINING 1 #define DEFINING 1
#define NOTHING 2 #define NOTHING 2
/** Return the hash value of the specified string. */
unsigned hash(char *string);
num_p numlookup(unsigned number);
/** Search the hash table for the specified name
* and symbol type specified in `flags`.
*/
sym_p symlookup(char *name, int status, int flags);
#endif /* LOOKUP_H_ */

View file

@ -1,72 +1,99 @@
#ifndef NORCSID
static char rcsid[] = "$Id$";
#endif
#include <stdlib.h>
#include <stdio.h>
#include "param.h"
#include "types.h"
#include "tes.h"
#include "alloc.h"
#include <em_spec.h>
#include "ext.h"
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
* *
* Author: Hans van Staveren * Author: Hans van Staveren
*/ */
#include <stdlib.h>
#include <stdio.h>
#include "param.h"
#include "types.h"
#include "tes.h"
#include "alloc.h"
#include "system.h"
#include <em_spec.h>
#include "ext.h"
#include "util.h"
#include "getline.h"
#include "putline.h"
/* Other external definitions */
extern void cleanup(void);
void flags(register char *s)
{
for (s++; *s; s++)
switch (*s)
{
case 'L':
Lflag = TRUE;
break;
case 'n':
nflag = TRUE;
break;
case 'm':
if (*(s + 1) == 'l')
{
s++;
repl_longmuls = TRUE;
}
repl_muls = atoi(s + 1);
break;
}
}
void fileinit(void)
{
if (readshort() != (short) sp_magic)
error("wrong input file");
if (Lflag)
{
if (sys_tmpnam(tempname)==NULL)
{
error("can't create temporary file.");
}
outfile = fopen(tempname, "wb");
if (outfile == NULL)
error("can't create %s", tempname);
}
else
{
outfile = stdout;
outshort(sp_magic);
}
}
/* /*
* Main program for EM optimizer * Main program for EM optimizer
*/ */
main(argc,argv) int argc; char *argv[]; { int main(int argc, char* argv[])
{
#ifndef USEMALLOC
int somespace[STACKROOM]; int somespace[STACKROOM];
#endif
progname = argv[0]; progname = argv[0];
while (argc-- > 1 && **++argv == '-') while (argc-- > 1 && **++argv == '-')
flags(*argv); flags(*argv);
if (argc>1) { if (argc > 1)
{
fprintf(stderr, "Usage: %s [-Ln] [-m<num>] [name]\n", progname); fprintf(stderr, "Usage: %s [-Ln] [-m<num>] [name]\n", progname);
exit(-1); exit(EXIT_FAILURE);
} }
if (argc) if (argc)
if (freopen(*argv, "r", stdin) == NULL) if (freopen(*argv, "r", stdin) == NULL)
error("Cannot open %s", *argv); error("Cannot open %s", *argv);
fileinit(); fileinit();
#ifdef USEMALLOC
coreinit();
#else
coreinit((short *) somespace, (short *) (somespace + STACKROOM)); coreinit((short *) somespace, (short *) (somespace + STACKROOM));
#endif
getlines(); getlines();
cleanup(); cleanup();
return(0); return (EXIT_SUCCESS);
} }
flags(s) register char *s; {
for (s++;*s;s++)
switch(*s) {
case 'L': Lflag = TRUE; break;
case 'n': nflag = TRUE; break;
case 'm': if (*(s+1) == 'l') {
s++;
repl_longmuls = TRUE;
}
repl_muls = atoi(s+1); break;
}
}
fileinit() {
short readshort();
if (readshort() != (short) sp_magic)
error("wrong input file");
if (Lflag) {
outfile = fdopen(mkstemp(template),"w");
if (outfile == NULL)
error("can't create %s",template);
} else {
outfile = stdout;
outshort(sp_magic);
}
}

View file

@ -1,8 +1,10 @@
%{ %{
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -13,12 +15,7 @@ static char rcsid[] = "$Id$";
#include <em_mnem.h> #include <em_mnem.h>
#include "optim.h" #include "optim.h"
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#define op_CBO (op_plast+1) #define op_CBO (op_plast+1)
@ -48,6 +45,22 @@ int CBO_instrs[] = {
int patCBO; int patCBO;
int rplCBO; int rplCBO;
/* Forward declarations */
void inithash(void);
unsigned hashname(register char *name);
void enter(char *name,int value);
int mlookup(char* name);
int lookup(int comm,int operator,int lnode,int rnode);
void printnodes(void);
void initio(void);
void outpat(int exprno, int instrno);
void outbyte(int b);
void outshort(int s);
void out(int w);
int yylex(void);
void yyerror(const char*);
%} %}
%union { %union {
@ -241,8 +254,9 @@ struct hashmnem {
byte h_value; byte h_value;
} hashmnem[HASHSIZE]; } hashmnem[HASHSIZE];
inithash() { void inithash(void)
register i; {
register int i;
enter("lab",op_lab); enter("lab",op_lab);
enter("LLP",op_LLP); enter("LLP",op_LLP);
@ -254,7 +268,8 @@ inithash() {
enter(em_mnem[i],i+sp_fmnem); enter(em_mnem[i],i+sp_fmnem);
} }
unsigned hashname(name) register char *name; { unsigned hashname(register char *name)
{
register unsigned h; register unsigned h;
h = (*name++)&BMASK; h = (*name++)&BMASK;
@ -263,7 +278,8 @@ unsigned hashname(name) register char *name; {
return(h); return(h);
} }
enter(name,value) char *name; { void enter(char *name,int value)
{
register unsigned h; register unsigned h;
h=hashname(name)%HASHSIZE; h=hashname(name)%HASHSIZE;
@ -273,7 +289,8 @@ enter(name,value) char *name; {
hashmnem[h].h_value = value; hashmnem[h].h_value = value;
} }
int mlookup(name) char *name; { int mlookup(char* name)
{
register unsigned h; register unsigned h;
h = hashname(name)%HASHSIZE; h = hashname(name)%HASHSIZE;
@ -283,8 +300,8 @@ int mlookup(name) char *name; {
return(hashmnem[h].h_value&BMASK); /* 0 if not found */ return(hashmnem[h].h_value&BMASK); /* 0 if not found */
} }
main() { int main(void)
{
inithash(); inithash();
initio(); initio();
yyparse(); yyparse();
@ -293,24 +310,26 @@ main() {
return nerrors; return nerrors;
} }
int yywrap(void) { int yywrap(void)
{
return 1; return 1;
} }
yyerror(s) char *s; { void yyerror(const char *s)
{
fprintf(stderr,"line %d: %s\n",lino,s); fprintf(stderr,"line %d: %s\n",lino,s);
nerrors++; nerrors++;
} }
lookup(comm,operator,lnode,rnode) { int lookup(int comm,int operator,int lnode,int rnode) {
register expr_p p; register expr_p p;
for (p=nodes+1;p<lastnode;p++) { for (p=nodes+1;p<lastnode;p++) {
if (p->ex_operator != operator) if (p->ex_operator != operator)
continue; continue;
if (!(p->ex_lnode == lnode && p->ex_rnode == rnode || if (!((p->ex_lnode == lnode && p->ex_rnode == rnode) ||
comm && p->ex_lnode == rnode && p->ex_rnode == lnode)) (comm && p->ex_lnode == rnode && p->ex_rnode == lnode)))
continue; continue;
return(p-nodes); return(p-nodes);
} }
@ -323,20 +342,22 @@ lookup(comm,operator,lnode,rnode) {
return(p-nodes); return(p-nodes);
} }
printnodes() { void printnodes(void)
{
register expr_p p; register expr_p p;
printf("};\n\nshort lastind = %d;\n\nexpr_t enodes[] = {\n",prevind); printf("};\n\nshort lastind = %d;\n\nexpr_t enodes[] = {\n",prevind);
for (p=nodes;p<lastnode;p++) for (p=nodes;p<lastnode;p++)
printf("/* %3d */\t%3d,%6u,%6u,\n", printf("/* %3d */\t{%3d,%6u,%6u},\n",
p-nodes,p->ex_operator,p->ex_lnode,p->ex_rnode); p-nodes,p->ex_operator,p->ex_lnode,p->ex_rnode);
printf("};\n\niarg_t iargs[%d];\n", (maxpatlen>0 ? maxpatlen : 1)); printf("};\n\niarg_t iargs[%d];\n", (maxpatlen>0 ? maxpatlen : 1));
if (patid[0]) if (patid[0])
printf("static char rcsid[] = %s;\n",patid); printf("static char rcsid[] = %s;\n",patid);
} }
initio() { void initio(void)
register i; {
register int i;
printf("#include \"param.h\"\n#include \"types.h\"\n"); printf("#include \"param.h\"\n#include \"types.h\"\n");
printf("#include \"pattern.h\"\n\n"); printf("#include \"pattern.h\"\n\n");
@ -377,7 +398,7 @@ initio() {
curind = 1; curind = 1;
} }
outpat(exprno, instrno) void outpat(int exprno, int instrno)
{ {
register int i; register int i;
@ -403,20 +424,20 @@ outpat(exprno, instrno)
if (patlen>maxpatlen) maxpatlen=patlen; if (patlen>maxpatlen) maxpatlen=patlen;
} }
outbyte(b) { void outbyte(int b)
{
printf(",%3d",b); printf(",%3d",b);
curind++; curind++;
} }
outshort(s) { void outshort(int s)
{
outbyte(s&0377); outbyte(s&0377);
outbyte((s>>8)&0377); outbyte((s>>8)&0377);
} }
out(w) { void out(int w)
{
if (w<255) { if (w<255) {
outbyte(w); outbyte(w);
} else { } else {

View file

@ -1,4 +1,4 @@
"$Id$"
inc dec: inc dec:
inc loc adi $3==w: loc $2+1 adi w inc loc adi $3==w: loc $2+1 adi w
inc loc sbi $3==w: loc $2-1 sbi w inc loc sbi $3==w: loc $2-1 sbi w

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h> #include <assert.h>
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
@ -10,19 +12,13 @@ static char rcsid[] = "$Id$";
#include "lookup.h" #include "lookup.h"
#include "proinf.h" #include "proinf.h"
#include "alloc.h" #include "alloc.h"
#include "reg.h"
#include "pattern.h" #include "pattern.h"
#include <em_spec.h> #include <em_spec.h>
#include <em_mnem.h> #include <em_mnem.h>
#include "optim.h" #include "optim.h"
#include "ext.h" #include "ext.h"
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#undef CHK_HASH /* print numbers patterns are hashed to */ #undef CHK_HASH /* print numbers patterns are hashed to */
#ifdef CHK_HASH #ifdef CHK_HASH
#include <stdio.h> #include <stdio.h>
@ -32,15 +28,24 @@ static char rcsid[] = "$Id$";
short pathash[256]; /* table of indices into pattern[] */ short pathash[256]; /* table of indices into pattern[] */
int opind = 0; /* second index of next matrix */ int opind = 0; /* second index of next matrix */
byte transl[op_plast-op_pfirst+1][3] = { byte transl[op_plast - op_pfirst + 1][3] =
/* LLP */ { op_LLP, op_lol, op_ldl }, {
/* LEP */ { op_LEP, op_loe, op_lde }, /* LLP */
/* SLP */ { op_SLP, op_stl, op_sdl }, { op_LLP, op_lol, op_ldl },
/* SEP */ { op_SEP, op_ste, op_sde } /* LEP */
}; { op_LEP, op_loe, op_lde },
/* SLP */
{ op_SLP, op_stl, op_sdl },
/* SEP */
{ op_SEP, op_ste, op_sde } };
opcheck(bp) register byte *bp; { /* Forward declarations */
static int repl_mul(register line_p, line_p *, line_p *);
static int optimize(void);
static int basicblock(line_p *);
static void opcheck(register byte *bp)
{
if (((*bp) & BMASK) >= op_pfirst) if (((*bp) & BMASK) >= op_pfirst)
*bp = transl[((*bp) & BMASK) - op_pfirst][opind]; *bp = transl[((*bp) & BMASK) - op_pfirst][opind];
} }
@ -54,7 +59,8 @@ opcheck(bp) register byte *bp; {
* Estimated improvement possible: about 2% * Estimated improvement possible: about 2%
*/ */
hashpatterns() { static void hashpatterns(void)
{
short index; short index;
register byte *bp, *tp; register byte *bp, *tp;
register short i; register short i;
@ -67,11 +73,13 @@ hashpatterns() {
else if (pointersize == 2 * wordsize) else if (pointersize == 2 * wordsize)
opind = 2; opind = 2;
index = lastind; /* set by mktab */ index = lastind; /* set by mktab */
while (index != 0) { while (index != 0)
{
bp = &pattern[index]; bp = &pattern[index];
tp = &bp[PO_MATCH]; tp = &bp[PO_MATCH];
i = *tp++ & BMASK; i = *tp++ & BMASK;
if (i==BMASK) { if (i == BMASK)
{
i = *tp++ & BMASK; i = *tp++ & BMASK;
i |= (*tp++ & BMASK) << 8; i |= (*tp++ & BMASK) << 8;
} }
@ -82,11 +90,13 @@ hashpatterns() {
if ((*tp++ & BMASK) == BMASK) if ((*tp++ & BMASK) == BMASK)
tp += 2; tp += 2;
i = *tp++ & BMASK; i = *tp++ & BMASK;
if (i==BMASK) { if (i == BMASK)
{
i = *tp++ & BMASK; i = *tp++ & BMASK;
i |= (*tp++ & BMASK) << 8; i |= (*tp++ & BMASK) << 8;
} }
while (i--) { while (i--)
{
opcheck(tp++); opcheck(tp++);
if ((*tp++ & BMASK) == BMASK) if ((*tp++ & BMASK) == BMASK)
tp += 2; tp += 2;
@ -99,7 +109,8 @@ hashpatterns() {
hashvalue = 0; hashvalue = 0;
tp = save; tp = save;
switch(patlen) { switch (patlen)
{
default: /* 3 or more */ default: /* 3 or more */
hashvalue = (hashvalue << 4) ^ (*tp++ & BMASK); hashvalue = (hashvalue << 4) ^ (*tp++ & BMASK);
case 2: case 2:
@ -121,59 +132,70 @@ hashpatterns() {
} }
} }
peephole() { int peephole(void)
{
static bool phashed = FALSE; static bool phashed = FALSE;
if (!phashed) { if (!phashed)
{
hashpatterns(); hashpatterns();
phashed = TRUE; phashed = TRUE;
} }
return optimize(); return optimize();
} }
optimize() { static int optimize(void)
{
register num_p *npp, np; register num_p *npp, np;
register instr; register int instr;
bool madeopt; bool madeopt;
madeopt = basicblock(&instrs); madeopt = basicblock(&instrs);
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np=np->n_next) { for (np = *npp; np != (num_p) 0; np = np->n_next)
if (! np->n_line) continue; {
if (!np->n_line)
continue;
if (np->n_line->l_next == (line_p) 0) if (np->n_line->l_next == (line_p) 0)
continue; continue;
instr = np->n_line->l_next->l_instr & BMASK; instr = np->n_line->l_next->l_instr & BMASK;
if (instr == op_lab || instr == op_bra) if (instr == op_lab || instr == op_bra)
np->n_repl = np->n_line->l_next->l_a.la_np; np->n_repl = np->n_line->l_next->l_a.la_np;
else else if (basicblock(&np->n_line->l_next))
if (basicblock(&np->n_line->l_next))
madeopt = TRUE; madeopt = TRUE;
} }
return madeopt; return madeopt;
} }
offset oabs(off) offset off; { static offset oabs(offset off)
{
return (off >= 0 ? off : -off); return (off >= 0 ? off : -off);
} }
line_p repline(ev,patlen) eval_t ev; { static line_p repline(eval_t ev, int patlen)
{
register line_p lp; register line_p lp;
register iarg_p iap; register iarg_p iap;
register sym_p sp; register sym_p sp;
offset diff, newdiff; offset diff, newdiff;
assert(ev.e_typ != EV_UNDEF); assert(ev.e_typ != EV_UNDEF);
switch(ev.e_typ) { switch (ev.e_typ)
{
case EV_CONST: case EV_CONST:
if ((short) ev.e_v.e_con == ev.e_v.e_con) { if ((short) ev.e_v.e_con == ev.e_v.e_con)
{
if (CANMINI((short ) ev.e_v.e_con)) if (CANMINI((short ) ev.e_v.e_con))
lp = newline((short) (ev.e_v.e_con) + Z_OPMINI); lp = newline((short) (ev.e_v.e_con) + Z_OPMINI);
else { else
{
lp = newline(OPSHORT); lp = newline(OPSHORT);
lp->l_a.la_short = (short) ev.e_v.e_con; lp->l_a.la_short = (short) ev.e_v.e_con;
} }
} else { }
else
{
lp = newline(OPOFFSET); lp = newline(OPOFFSET);
lp->l_a.la_offset = ev.e_v.e_con; lp->l_a.la_offset = ev.e_v.e_con;
} }
@ -192,7 +214,8 @@ line_p repline(ev,patlen) eval_t ev; {
*/ */
sp = (sym_p) 0; sp = (sym_p) 0;
for (iap = &iargs[patlen - 1]; iap >= iargs; iap--) for (iap = &iargs[patlen - 1]; iap >= iargs; iap--)
if (iap->ia_ev.e_typ == ev.e_typ) { if (iap->ia_ev.e_typ == ev.e_typ)
{
/* /*
* Although lint complains, diff is not used * Although lint complains, diff is not used
* before set. * before set.
@ -201,22 +224,29 @@ line_p repline(ev,patlen) eval_t ev; {
* reader. * reader.
*/ */
newdiff = oabs(iap->ia_sp->s_value - ev.e_v.e_con); newdiff = oabs(iap->ia_sp->s_value - ev.e_v.e_con);
if (sp==(sym_p) 0 || newdiff < diff) { if (sp == (sym_p) 0 || newdiff < diff)
{
sp = iap->ia_sp; sp = iap->ia_sp;
diff = newdiff; diff = newdiff;
} }
} }
assert(sp != (sym_p ) 0); assert(sp != (sym_p ) 0);
if (diff == 0) { if (diff == 0)
{
lp = newline(OPSYMBOL); lp = newline(OPSYMBOL);
lp->l_a.la_sp = sp; lp->l_a.la_sp = sp;
} else { }
else
{
diff = ev.e_v.e_con - sp->s_value; diff = ev.e_v.e_con - sp->s_value;
if ((short) diff == diff) { if ((short) diff == diff)
{
lp = newline(OPSVAL); lp = newline(OPSVAL);
lp->l_a.la_sval.lasv_short = (short) diff; lp->l_a.la_sval.lasv_short = (short) diff;
lp->l_a.la_sval.lasv_sp = sp; lp->l_a.la_sval.lasv_sp = sp;
} else { }
else
{
lp = newline(OPLVAL); lp = newline(OPLVAL);
lp->l_a.la_lval.lalv_offset = diff; lp->l_a.la_lval.lalv_offset = diff;
lp->l_a.la_lval.lalv_sp = sp; lp->l_a.la_lval.lalv_sp = sp;
@ -226,7 +256,8 @@ line_p repline(ev,patlen) eval_t ev; {
} }
} }
offset rotate(w,amount) offset w,amount; { static offset rotate(offset w, offset amount)
{
offset highmask, lowmask; offset highmask, lowmask;
#ifndef LONGOFF #ifndef LONGOFF
@ -236,31 +267,35 @@ offset rotate(w,amount) offset w,amount; {
lowmask = ~highmask; lowmask = ~highmask;
if (wordsize != 4) if (wordsize != 4)
highmask &= wordsize == 2 ? 0xFFFF : 0xFF; highmask &= wordsize == 2 ? 0xFFFF : 0xFF;
return(((w<<amount)&highmask)|((w>>(8*wordsize-amount))&lowmask)); return (((w << amount) & highmask)
| ((w >> (8 * wordsize - amount)) & lowmask));
} }
eval_t undefres = { EV_UNDEF }; eval_t undefres =
{ EV_UNDEF };
eval_t compute(pexp) register expr_p pexp; { static eval_t compute(register expr_p pexp)
{
eval_t leaf1, leaf2, res; eval_t leaf1, leaf2, res;
register i; register int i;
register sym_p sp; register sym_p sp;
offset mask; offset mask;
switch(nparam[pexp->ex_operator]) { switch (nparam[pexp->ex_operator])
{
default: default:
assert(FALSE); assert(FALSE);
case 2: case 2:
leaf2 = compute(&enodes[pexp->ex_rnode]); leaf2 = compute(&enodes[pexp->ex_rnode]);
if (leaf2.e_typ == EV_UNDEF || if (leaf2.e_typ == EV_UNDEF
nonumlab[pexp->ex_operator] && leaf2.e_typ == EV_NUMLAB || || (nonumlab[pexp->ex_operator] && leaf2.e_typ == EV_NUMLAB)
onlyconst[pexp->ex_operator] && leaf2.e_typ != EV_CONST) || (onlyconst[pexp->ex_operator] && leaf2.e_typ != EV_CONST))
return (undefres); return (undefres);
case 1: case 1:
leaf1 = compute(&enodes[pexp->ex_lnode]); leaf1 = compute(&enodes[pexp->ex_lnode]);
if (leaf1.e_typ == EV_UNDEF || if (leaf1.e_typ == EV_UNDEF
nonumlab[pexp->ex_operator] && leaf1.e_typ == EV_NUMLAB || || (nonumlab[pexp->ex_operator] && leaf1.e_typ == EV_NUMLAB)
onlyconst[pexp->ex_operator] && leaf1.e_typ != EV_CONST) || (onlyconst[pexp->ex_operator] && leaf1.e_typ != EV_CONST))
return (undefres); return (undefres);
case 0: case 0:
break; break;
@ -268,9 +303,11 @@ eval_t compute(pexp) register expr_p pexp; {
res.e_typ = EV_CONST; res.e_typ = EV_CONST;
res.e_v.e_con = 0; res.e_v.e_con = 0;
switch(pexp->ex_operator) { switch (pexp->ex_operator)
{
default: default:
assert(FALSE); assert(FALSE);
break;
case EX_CON: case EX_CON:
res.e_v.e_con = (offset) pexp->ex_lnode; res.e_v.e_con = (offset) pexp->ex_lnode;
break; break;
@ -279,7 +316,8 @@ eval_t compute(pexp) register expr_p pexp; {
case EX_CMPEQ: case EX_CMPEQ:
if (leaf1.e_typ != leaf2.e_typ) if (leaf1.e_typ != leaf2.e_typ)
return (undefres); return (undefres);
if (leaf1.e_typ == EV_NUMLAB) { if (leaf1.e_typ == EV_NUMLAB)
{
if (leaf1.e_v.e_np == leaf2.e_v.e_np) if (leaf1.e_v.e_np == leaf2.e_v.e_np)
res.e_v.e_con = 1; res.e_v.e_con = 1;
break; break;
@ -288,11 +326,13 @@ eval_t compute(pexp) register expr_p pexp; {
res.e_v.e_con = 1; res.e_v.e_con = 1;
break; break;
case EX_CMPNE: case EX_CMPNE:
if (leaf1.e_typ != leaf2.e_typ) { if (leaf1.e_typ != leaf2.e_typ)
{
res.e_v.e_con = 1; res.e_v.e_con = 1;
break; break;
} }
if (leaf1.e_typ == EV_NUMLAB) { if (leaf1.e_typ == EV_NUMLAB)
{
if (leaf1.e_v.e_np != leaf2.e_v.e_np) if (leaf1.e_v.e_np != leaf2.e_v.e_np)
res.e_v.e_con = 1; res.e_v.e_con = 1;
break; break;
@ -368,21 +408,25 @@ eval_t compute(pexp) register expr_p pexp; {
res.e_v.e_con = ~leaf1.e_v.e_con; res.e_v.e_con = ~leaf1.e_v.e_con;
break; break;
case EX_PLUS: case EX_PLUS:
if (leaf1.e_typ >= EV_FRAG) { if (leaf1.e_typ >= EV_FRAG)
{
if (leaf2.e_typ >= EV_FRAG) if (leaf2.e_typ >= EV_FRAG)
return (undefres); return (undefres);
res.e_typ = leaf1.e_typ; res.e_typ = leaf1.e_typ;
} else }
else
res.e_typ = leaf2.e_typ; res.e_typ = leaf2.e_typ;
res.e_v.e_con = leaf1.e_v.e_con + leaf2.e_v.e_con; res.e_v.e_con = leaf1.e_v.e_con + leaf2.e_v.e_con;
break; break;
case EX_MINUS: case EX_MINUS:
if (leaf1.e_typ >= EV_FRAG) { if (leaf1.e_typ >= EV_FRAG)
{
if (leaf2.e_typ == EV_CONST) if (leaf2.e_typ == EV_CONST)
res.e_typ = leaf1.e_typ; res.e_typ = leaf1.e_typ;
else if (leaf2.e_typ != leaf1.e_typ) else if (leaf2.e_typ != leaf1.e_typ)
return (undefres); return (undefres);
} else if (leaf2.e_typ >= EV_FRAG) }
else if (leaf2.e_typ >= EV_FRAG)
return (undefres); return (undefres);
res.e_v.e_con = leaf1.e_v.e_con - leaf2.e_v.e_con; res.e_v.e_con = leaf1.e_v.e_con - leaf2.e_v.e_con;
break; break;
@ -403,27 +447,28 @@ eval_t compute(pexp) register expr_p pexp; {
res.e_v.e_con = (leaf1.e_v.e_con ^ leaf2.e_v.e_con) >= 0; res.e_v.e_con = (leaf1.e_v.e_con ^ leaf2.e_v.e_con) >= 0;
break; break;
case EX_ROM: case EX_ROM:
if ((sp = iargs[pexp->ex_lnode - 1].ia_sp) != (sym_p) 0 && if ((sp = iargs[pexp->ex_lnode - 1].ia_sp) != (sym_p) 0
sp->s_rom != (offset *) 0) { && sp->s_rom != (offset *) 0)
{
leaf2 = compute(&enodes[pexp->ex_rnode]); leaf2 = compute(&enodes[pexp->ex_rnode]);
if (leaf2.e_typ != EV_CONST || if (leaf2.e_typ != EV_CONST || leaf2.e_v.e_con < 0||
leaf2.e_v.e_con < 0 ||
leaf2.e_v.e_con >= MAXROM) leaf2.e_v.e_con >= MAXROM)
return (undefres); return (undefres);
res.e_v.e_con = sp->s_rom[(int) (leaf2.e_v.e_con)]; res.e_v.e_con = sp->s_rom[(int) (leaf2.e_v.e_con)];
break; break;
} else }
else
return (undefres); return (undefres);
case EX_SFIT: case EX_SFIT:
mask = 0; mask = 0;
for (i=leaf2.e_v.e_con - 1;i < 8*sizeof(offset); i++) for (i = leaf2.e_v.e_con - 1; i < (int)(8 * sizeof(offset)); i++)
mask |= ((offset) 1) << i; mask |= ((offset) 1) << i;
res.e_v.e_con = (leaf1.e_v.e_con&mask) == 0 || res.e_v.e_con = (leaf1.e_v.e_con & mask) == 0
(leaf1.e_v.e_con&mask) == mask; || (leaf1.e_v.e_con & mask) == mask;
break; break;
case EX_UFIT: case EX_UFIT:
mask = 0; mask = 0;
for (i=leaf2.e_v.e_con;i < 8*sizeof(offset); i++) for (i = leaf2.e_v.e_con; i < (int)(8 * sizeof(offset)); i++)
mask |= ((offset) 1) << i; mask |= ((offset) 1) << i;
res.e_v.e_con = (leaf1.e_v.e_con & mask) == 0; res.e_v.e_con = (leaf1.e_v.e_con & mask) == 0;
break; break;
@ -438,17 +483,15 @@ eval_t compute(pexp) register expr_p pexp; {
extern bool special(); extern bool special();
#endif #endif
bool tryrepl(lpp,bp,patlen) static bool tryrepl(line_p *lpp, register byte *bp, int patlen)
line_p *lpp;
register byte *bp;
int patlen;
{ {
int rpllen, instr, rplval; int rpllen, instr, rplval;
register line_p lp; register line_p lp;
line_p replacement, *rlpp, tp; line_p replacement, *rlpp, tp;
rpllen = *bp++ & BMASK; rpllen = *bp++ & BMASK;
if (rpllen == BMASK) { if (rpllen == BMASK)
{
rpllen = *bp++ & BMASK; rpllen = *bp++ & BMASK;
rpllen |= (*bp++ & BMASK) << 8; rpllen |= (*bp++ & BMASK) << 8;
} }
@ -458,10 +501,12 @@ int patlen;
#endif #endif
replacement = (line_p) 0; replacement = (line_p) 0;
rlpp = &replacement; rlpp = &replacement;
while (rpllen--) { while (rpllen--)
{
instr = *bp++ & BMASK; instr = *bp++ & BMASK;
rplval = *bp++ & BMASK; rplval = *bp++ & BMASK;
if (rplval == BMASK) { if (rplval == BMASK)
{
rplval = (*bp++ & BMASK); rplval = (*bp++ & BMASK);
rplval |= (*bp++ & BMASK) << 8; rplval |= (*bp++ & BMASK) << 8;
} }
@ -486,7 +531,6 @@ int patlen;
* Replace instructions matched by the created replacement * Replace instructions matched by the created replacement
*/ */
OPTIM((bp[0]&BMASK)|(bp[1]&BMASK)<<8); OPTIM((bp[0]&BMASK)|(bp[1]&BMASK)<<8);
for (lp = *lpp; patlen > 0; patlen--, tp = lp, lp = lp->l_next) for (lp = *lpp; patlen > 0; patlen--, tp = lp, lp = lp->l_next)
; ;
@ -494,7 +538,8 @@ int patlen;
*rlpp = lp; *rlpp = lp;
lp = *lpp; lp = *lpp;
*lpp = replacement; *lpp = replacement;
while ( lp != (line_p) 0 ) { while (lp != (line_p) 0)
{
tp = lp->l_next; tp = lp->l_next;
oldline(lp); oldline(lp);
lp = tp; lp = tp;
@ -502,10 +547,7 @@ int patlen;
return (TRUE); return (TRUE);
} }
bool trypat(lpp,bp,len) static bool trypat(line_p *lpp, register byte *bp, int len)
line_p *lpp;
register byte *bp;
int len;
{ {
register iarg_p iap; register iarg_p iap;
int i, patlen; int i, patlen;
@ -513,14 +555,18 @@ int len;
eval_t result; eval_t result;
patlen = *bp++ & BMASK; patlen = *bp++ & BMASK;
if (patlen == BMASK) { if (patlen == BMASK)
{
patlen = *bp++ & BMASK; patlen = *bp++ & BMASK;
patlen |= (*bp++ & BMASK) << 8; patlen |= (*bp++ & BMASK) << 8;
} }
if (len == 3) { if (len == 3)
{
if (patlen < 3) if (patlen < 3)
return (FALSE); return (FALSE);
} else { }
else
{
if (patlen != len) if (patlen != len)
return (FALSE); return (FALSE);
} }
@ -539,8 +585,10 @@ int len;
* opcodes are also correct, now comes the hard part * opcodes are also correct, now comes the hard part
*/ */
for(i=0,lp= *lpp,iap= iargs; i<patlen;i++,iap++,lp=lp->l_next) { for (i = 0, lp = *lpp, iap = iargs; i < patlen; i++, iap++, lp = lp->l_next)
switch(lp->l_optyp) { {
switch (lp->l_optyp)
{
case OPNO: case OPNO:
iap->ia_ev.e_typ = EV_UNDEF; iap->ia_ev.e_typ = EV_UNDEF;
break; break;
@ -570,23 +618,27 @@ int len;
case OPSVAL: case OPSVAL:
iap->ia_ev.e_typ = lp->l_a.la_sval.lasv_sp->s_frag; iap->ia_ev.e_typ = lp->l_a.la_sval.lasv_sp->s_frag;
iap->ia_sp = lp->l_a.la_sval.lasv_sp; iap->ia_sp = lp->l_a.la_sval.lasv_sp;
iap->ia_ev.e_v.e_con = lp->l_a.la_sval.lasv_sp->s_value + lp->l_a.la_sval.lasv_short; iap->ia_ev.e_v.e_con = lp->l_a.la_sval.lasv_sp->s_value
+ lp->l_a.la_sval.lasv_short;
break; break;
#ifdef LONGOFF #ifdef LONGOFF
case OPLVAL: case OPLVAL:
iap->ia_ev.e_typ = lp->l_a.la_lval.lalv_sp->s_frag; iap->ia_ev.e_typ = lp->l_a.la_lval.lalv_sp->s_frag;
iap->ia_sp = lp->l_a.la_lval.lalv_sp; iap->ia_sp = lp->l_a.la_lval.lalv_sp;
iap->ia_ev.e_v.e_con = lp->l_a.la_lval.lalv_sp->s_value + lp->l_a.la_lval.lalv_offset; iap->ia_ev.e_v.e_con = lp->l_a.la_lval.lalv_sp->s_value
+ lp->l_a.la_lval.lalv_offset;
break; break;
#endif #endif
} }
} }
i = *bp++ & BMASK; i = *bp++ & BMASK;
if ( i==BMASK ) { if (i == BMASK)
{
i = *bp++ & BMASK; i = *bp++ & BMASK;
i |= (*bp++ & BMASK) << 8; i |= (*bp++ & BMASK) << 8;
} }
if ( i != 0) { if (i != 0)
{
/* there is a condition */ /* there is a condition */
result = compute(&enodes[i]); result = compute(&enodes[i]);
if (result.e_typ != EV_CONST || result.e_v.e_con == 0) if (result.e_typ != EV_CONST || result.e_v.e_con == 0)
@ -595,8 +647,8 @@ int len;
return (tryrepl(lpp, bp, patlen)); return (tryrepl(lpp, bp, patlen));
} }
int static int basicblock(line_p *alpp)
basicblock(alpp) line_p *alpp; { {
register line_p *lpp, lp; register line_p *lpp, lp;
unsigned short hash[3]; unsigned short hash[3];
line_p *next; line_p *next;
@ -606,20 +658,25 @@ basicblock(alpp) line_p *alpp; {
bool madeopt; bool madeopt;
int count = 0; int count = 0;
lpp = alpp; madeopt = FALSE; lpp = alpp;
while ((*lpp) != (line_p) 0 && ((*lpp)->l_instr&BMASK) != op_lab) { madeopt = FALSE;
while ((*lpp) != (line_p) 0 && ((*lpp)->l_instr & BMASK) != op_lab)
{
lp = *lpp; lp = *lpp;
next = &lp->l_next; next = &lp->l_next;
hash[0] = lp->l_instr & BMASK; hash[0] = lp->l_instr & BMASK;
lp = lp->l_next; lp = lp->l_next;
if (lp != (line_p) 0) { if (lp != (line_p) 0)
{
hash[1] = (hash[0] << 4) ^ (lp->l_instr & BMASK); hash[1] = (hash[0] << 4) ^ (lp->l_instr & BMASK);
lp = lp->l_next; lp = lp->l_next;
if (lp != (line_p) 0) if (lp != (line_p) 0)
hash[2] = (hash[1] << 4) ^ (lp->l_instr & BMASK); hash[2] = (hash[1] << 4) ^ (lp->l_instr & BMASK);
else else
hash[2] = ILLHASH; hash[2] = ILLHASH;
} else { }
else
{
hash[1] = ILLHASH; hash[1] = ILLHASH;
hash[2] = ILLHASH; hash[2] = ILLHASH;
} }
@ -628,12 +685,15 @@ basicblock(alpp) line_p *alpp; {
* hashvalues computed. Try for longest pattern first * hashvalues computed. Try for longest pattern first
*/ */
for (i=2;i>=0;i--) { for (i = 2; i >= 0; i--)
{
index = pathash[hash[i] & BMASK]; index = pathash[hash[i] & BMASK];
while (index != 0) { while (index != 0)
{
bp = &pattern[index]; bp = &pattern[index];
if ((bp[PO_HASH] & BMASK) == (hash[i] >> 8)) if ((bp[PO_HASH] & BMASK) == (hash[i] >> 8))
if(trypat(lpp,&bp[PO_MATCH],i+1)) { if (trypat(lpp, &bp[PO_MATCH], i + 1))
{
madeopt = TRUE; madeopt = TRUE;
next = lpp; next = lpp;
i = 0; /* dirty way of double break */ i = 0; /* dirty way of double break */
@ -642,25 +702,32 @@ basicblock(alpp) line_p *alpp; {
index = (bp[PO_NEXT] & BMASK) | (bp[PO_NEXT + 1] << 8); index = (bp[PO_NEXT] & BMASK) | (bp[PO_NEXT + 1] << 8);
} }
} }
if (lpp == next) { if (lpp == next)
{
count++; count++;
if (count > 1000) { if (count > 1000)
{
/* probably loop in table */ /* probably loop in table */
fprintf(stderr, "Warning: possible loop in patterns; call an expert\n"); fprintf(stderr,
"Warning: possible loop in patterns; call an expert\n");
next = &((*lpp)->l_next); next = &((*lpp)->l_next);
count = 0; count = 0;
} }
} }
else count = 0; else
count = 0;
lpp = next; lpp = next;
} }
lpp = alpp; lpp = alpp;
if (repl_muls) { if (repl_muls)
while ((lp = *lpp) != (line_p) 0 && (lp->l_instr&BMASK) != op_lab) { {
while ((lp = *lpp) != (line_p) 0 && (lp->l_instr & BMASK) != op_lab)
{
line_p b_repl, e_repl; line_p b_repl, e_repl;
int cnt; int cnt;
if ((cnt = (lp->l_instr & BMASK)) != op_loc && cnt != op_ldc) { if ((cnt = (lp->l_instr & BMASK)) != op_loc && cnt != op_ldc)
{
lpp = &lp->l_next; lpp = &lp->l_next;
continue; continue;
} }
@ -668,7 +735,8 @@ basicblock(alpp) line_p *alpp; {
cnt = repl_mul(lp, &b_repl, &e_repl); cnt = repl_mul(lp, &b_repl, &e_repl);
lp = *lpp; lp = *lpp;
if (cnt > 0 && cnt <= repl_muls) { if (cnt > 0 && cnt <= repl_muls)
{
*lpp = b_repl; *lpp = b_repl;
e_repl->l_next = lp->l_next->l_next; e_repl->l_next = lp->l_next->l_next;
oldline(lp->l_next); oldline(lp->l_next);
@ -676,8 +744,10 @@ basicblock(alpp) line_p *alpp; {
lpp = &e_repl->l_next; lpp = &e_repl->l_next;
madeopt = TRUE; madeopt = TRUE;
} }
else { else
while (b_repl != (line_p) 0) { {
while (b_repl != (line_p) 0)
{
line_p n = b_repl->l_next; line_p n = b_repl->l_next;
oldline(b_repl); oldline(b_repl);
@ -690,9 +760,7 @@ basicblock(alpp) line_p *alpp; {
return madeopt; return madeopt;
} }
repl_mul(lp, b, e) static int repl_mul(register line_p lp, line_p *b, line_p *e)
register line_p lp;
line_p *b, *e;
{ {
register line_p next = lp->l_next; register line_p next = lp->l_next;
int ins; int ins;
@ -703,11 +771,14 @@ repl_mul(lp, b, e)
int retval = 0; int retval = 0;
*b = 0; *b = 0;
if (! next) return 0; if (!next)
if ((ins = (next->l_instr & BMASK)) != op_mli && ins != op_mlu) { return 0;
if ((ins = (next->l_instr & BMASK)) != op_mli && ins != op_mlu)
{
return 0; return 0;
} }
switch(next->l_optyp) { switch (next->l_optyp)
{
case OPNO: case OPNO:
return 0; return 0;
case OPSHORT: case OPSHORT:
@ -722,10 +793,14 @@ repl_mul(lp, b, e)
sz = (next->l_optyp & BMASK) - Z_OPMINI; sz = (next->l_optyp & BMASK) - Z_OPMINI;
break; break;
} }
if (ins == op_loc && sz != wordsize) return 0; if (ins == op_loc && sz != wordsize)
if (ins == op_ldc && sz != 2*wordsize) return 0; return 0;
if (! repl_longmuls && sz != wordsize) return 0; if (ins == op_ldc && sz != 2 * wordsize)
switch(lp->l_optyp) { return 0;
if (!repl_longmuls && sz != wordsize)
return 0;
switch (lp->l_optyp)
{
case OPSHORT: case OPSHORT:
n = (long) lp->l_a.la_short; n = (long) lp->l_a.la_short;
break; break;
@ -741,79 +816,125 @@ repl_mul(lp, b, e)
#define newinstr(res, opcode, val) (*(res) = newline((short)(val)+Z_OPMINI), (*(res))->l_instr = (opcode)) #define newinstr(res, opcode, val) (*(res) = newline((short)(val)+Z_OPMINI), (*(res))->l_instr = (opcode))
while (n) { while (n)
{
/* first find "0*1*$" in n */ /* first find "0*1*$" in n */
for (n1 = 0; n & 1; n>>=1) ++n1; /* count "1" bits */ for (n1 = 0; n & 1; n >>= 1)
++n1; /* count "1" bits */
if (n) if (n)
for (n0 = 0; !(n & 1); n >>= 1) /* count "0" bits */ for (n0 = 0; !(n & 1); n >>= 1) /* count "0" bits */
++n0; ++n0;
else else
n0 = 0; n0 = 0;
if (n1 == 0) { if (n1 == 0)
if (n0) { {
newinstr(b, op_loc, n0); b = &((*b)->l_next); if (n0)
newinstr(b, op_slu, sz); b = &((*b)->l_next); {
newinstr(b, op_loc, n0);
b = &((*b)->l_next);
newinstr(b, op_slu, sz);
b = &((*b)->l_next);
retval++; retval++;
} }
} else if (n1 == 1) { }
if (virgin) { else if (n1 == 1)
newinstr(b, op_dup, sz); b = &((*b)->l_next); {
if (virgin)
{
newinstr(b, op_dup, sz);
b = &((*b)->l_next);
virgin = 0; virgin = 0;
} }
else { else
newinstr(b, op_exg, sz); b = &((*b)->l_next); {
newinstr(b, op_dup, 2*sz); b = &((*b)->l_next); newinstr(b, op_exg, sz);
newinstr(b, op_asp, sz); b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, op_adu, sz); b = &((*b)->l_next); newinstr(b, op_dup, 2 * sz);
newinstr(b, op_exg, sz); b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, op_asp, sz);
b = &((*b)->l_next);
newinstr(b, op_adu, sz);
b = &((*b)->l_next);
newinstr(b, op_exg, sz);
b = &((*b)->l_next);
retval++; retval++;
} }
if (n) { if (n)
newinstr(b, op_loc, n0+n1); b = &((*b)->l_next); {
newinstr(b, op_slu, sz); b = &((*b)->l_next); newinstr(b, op_loc, n0 + n1);
b = &((*b)->l_next);
newinstr(b, op_slu, sz);
b = &((*b)->l_next);
retval++; retval++;
} }
} else {
if (virgin) {
newinstr(b, op_dup, sz); b = &((*b)->l_next);
if (sz == wordsize) {
newinstr(b, op_loc, 0); b = &((*b)->l_next);
} }
else { else
newinstr(b, op_ldc, 0); b = &((*b)->l_next); {
if (virgin)
{
newinstr(b, op_dup, sz);
b = &((*b)->l_next);
if (sz == wordsize)
{
newinstr(b, op_loc, 0);
b = &((*b)->l_next);
} }
newinstr(b, op_exg, sz); b = &((*b)->l_next); else
{
newinstr(b, op_ldc, 0);
b = &((*b)->l_next);
}
newinstr(b, op_exg, sz);
b = &((*b)->l_next);
virgin = 0; virgin = 0;
} }
else { else
newinstr(b, op_exg, sz); b = &((*b)->l_next); {
newinstr(b, op_dup, 2*sz); b = &((*b)->l_next); newinstr(b, op_exg, sz);
newinstr(b, op_asp, sz); b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, op_dup, 2 * sz);
b = &((*b)->l_next);
newinstr(b, op_asp, sz);
b = &((*b)->l_next);
} }
newinstr(b, op_sbu, sz); b = &((*b)->l_next); newinstr(b, op_sbu, sz);
newinstr(b, op_exg, sz); b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, op_exg, sz);
b = &((*b)->l_next);
retval++; retval++;
if (n1 != 8*sz) { if (n1 != 8 * sz)
newinstr(b, op_loc, n1); b = &((*b)->l_next); {
newinstr(b, op_slu, sz); b = &((*b)->l_next); newinstr(b, op_loc, n1);
b = &((*b)->l_next);
newinstr(b, op_slu, sz);
b = &((*b)->l_next);
retval++; retval++;
newinstr(b, op_exg, sz); b = &((*b)->l_next); newinstr(b, op_exg, sz);
newinstr(b, op_dup, 2*sz); b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, op_asp, sz); b = &((*b)->l_next); newinstr(b, op_dup, 2 * sz);
newinstr(b, op_adu, sz); b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, op_exg, sz); b = &((*b)->l_next); newinstr(b, op_asp, sz);
b = &((*b)->l_next);
newinstr(b, op_adu, sz);
b = &((*b)->l_next);
newinstr(b, op_exg, sz);
b = &((*b)->l_next);
retval++; retval++;
} }
if (n0) { if (n0)
newinstr(b, op_loc, n0); b = &((*b)->l_next); {
newinstr(b, op_slu, sz); b = &((*b)->l_next); newinstr(b, op_loc, n0);
b = &((*b)->l_next);
newinstr(b, op_slu, sz);
b = &((*b)->l_next);
retval++; retval++;
} }
} }
} }
newinstr(b, op_asp, sz); newinstr(b, op_asp, sz);
if (virgin) { if (virgin)
{
b = &((*b)->l_next); b = &((*b)->l_next);
newinstr(b, sz == wordsize ? op_loc : op_ldc, 0); newinstr(b, sz == wordsize ? op_loc : op_ldc, 0);
} }

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h> #include <assert.h>
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
@ -9,57 +11,21 @@ static char rcsid[] = "$Id$";
#include <em_spec.h> #include <em_spec.h>
#include <em_pseu.h> #include <em_pseu.h>
#include "alloc.h" #include "alloc.h"
#include "util.h"
#include "putline.h"
#include "line.h" #include "line.h"
#include "reg.h"
#include "lookup.h" #include "lookup.h"
#include "proinf.h" #include "proinf.h"
#include "ext.h" #include "ext.h"
/* /* External definitions */
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. extern void flow(void);
* See the copyright notice in the ACK home directory, in the file "Copyright". extern void backward(void);
* extern int peephole(void);
* Author: Hans van Staveren
*/
process() { static void relabel(void)
{
if (wordsize == 0 || pointersize == 0)
error("No MES EMX encountered");
backward(); /* reverse and cleanup list */
symknown(); /* symbol scope is now known */
if (!nflag)
symvalue(); /* give symbols value */
if (prodepth != 0) {
if (!nflag) {
int npasses = 0;
bool madeopt;
checklocs(); /* check definition of locals */
do {
madeopt = peephole(); /* local optimization */
relabel(); /* relabel local labels */
flow(); /* throw away unreachable code */
} while (madeopt && ++npasses < 5000);
assert(!madeopt);
}
do_tes(); /* top elt. size computation phase */
outpro(); /* generate PRO pseudo */
outregs(); /* generate MES ms_reg pseudos */
outtes(); /* generate MES ms_tes pseudos */
}
putlines(pseudos); /* pseudos first */
if (prodepth != 0) {
putlines(instrs); /* instructions next */
outend(); /* generate END pseudo */
cleanlocals(); /* forget instruction labels */
} else if(instrs != (line_p) 0)
error("instructions outside procedure");
#ifdef COREDEBUG
coreverbose();
#endif
}
relabel() {
register num_p *npp, np, tp; register num_p *npp, np, tp;
register num_p repl, ttp; register num_p repl, ttp;
@ -70,15 +36,16 @@ relabel() {
*/ */
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np = np->n_next) { for (np = *npp; np != (num_p) 0; np = np->n_next)
assert(! np->n_line || {
((np->n_line->l_instr&BMASK) == op_lab assert(
&& np->n_line->l_a.la_np == np)); ! np->n_line || ((np->n_line->l_instr&BMASK) == op_lab && np->n_line->l_a.la_np == np));
for (tp = np; (tp->n_flags & (NUMKNOWN | NUMMARK)) == 0; for (tp = np; (tp->n_flags & (NUMKNOWN | NUMMARK)) == 0;
tp = tp->n_repl) tp = tp->n_repl)
tp->n_flags |= NUMMARK; tp->n_flags |= NUMMARK;
repl = tp->n_repl; repl = tp->n_repl;
for(tp=np; tp->n_flags&NUMMARK; tp = ttp) { for (tp = np; tp->n_flags & NUMMARK; tp = ttp)
{
ttp = tp->n_repl; ttp = tp->n_repl;
tp->n_repl = repl; tp->n_repl = repl;
tp->n_flags &= ~ NUMMARK; tp->n_flags &= ~ NUMMARK;
@ -86,13 +53,15 @@ relabel() {
} }
} }
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np = np->n_next) { for (np = *npp; np != (num_p) 0; np = np->n_next)
{
np->n_flags &= ~(NUMKNOWN | NUMSCAN | NUMREACH); np->n_flags &= ~(NUMKNOWN | NUMSCAN | NUMREACH);
np->n_jumps = 0; np->n_jumps = 0;
} }
} }
symknown() { static void symknown(void)
{
register sym_p *spp, sp; register sym_p *spp, sp;
for (spp = symhash; spp < &symhash[NSYMHASH]; spp++) for (spp = symhash; spp < &symhash[NSYMHASH]; spp++)
@ -101,12 +70,15 @@ symknown() {
sp->s_flags |= SYMKNOWN; sp->s_flags |= SYMKNOWN;
} }
cleanlocals() { static void cleanlocals(void)
{
register num_p *npp, np, tp; register num_p *npp, np, tp;
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) { for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
{
np = *npp; np = *npp;
while (np != (num_p) 0) { while (np != (num_p) 0)
{
tp = np->n_next; tp = np->n_next;
oldnum(np); oldnum(np);
np = tp; np = tp;
@ -115,23 +87,25 @@ cleanlocals() {
} }
} }
checklocs() { static void checklocs(void)
{
register num_p *npp, np; register num_p *npp, np;
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np = np->n_next) for (np = *npp; np != (num_p) 0; np = np->n_next)
if (np->n_line == (line_p) 0) if (np->n_line == (line_p) 0)
error("local label %u undefined", error("local label %u undefined", (unsigned) np->n_number);
(unsigned) np->n_number);
} }
offset align(count,alignment) offset count,alignment; { static offset align(offset count, offset alignment)
{
assert(alignment == 1 || alignment == 2 || alignment == 4); assert(alignment == 1 || alignment == 2 || alignment == 4);
return ((count + alignment - 1) & ~(alignment - 1)); return ((count + alignment - 1) & ~(alignment - 1));
} }
symvalue() { static void symvalue(void)
{
register line_p lp; register line_p lp;
register sym_p sp; register sym_p sp;
register arg_p ap; register arg_p ap;
@ -140,12 +114,15 @@ symvalue() {
offset count; offset count;
for (lp = pseudos; lp != (line_p) 0; lp = lp->l_next) for (lp = pseudos; lp != (line_p) 0; lp = lp->l_next)
switch(lp->l_instr&BMASK) { switch (lp->l_instr & BMASK)
{
default: default:
assert(FALSE); assert(FALSE);
break;
case ps_sym: case ps_sym:
sp = lp->l_a.la_sp; sp = lp->l_a.la_sp;
if (sp->s_frag != curfrag) { if (sp->s_frag != curfrag)
{
count = 0; count = 0;
curfrag = sp->s_frag; curfrag = sp->s_frag;
} }
@ -160,7 +137,8 @@ symvalue() {
case ps_con: case ps_con:
case ps_rom: case ps_rom:
for (ap = lp->l_a.la_arg; ap != (arg_p) 0; ap = ap->a_next) for (ap = lp->l_a.la_arg; ap != (arg_p) 0; ap = ap->a_next)
switch(ap->a_typ) { switch (ap->a_typ)
{
default: default:
assert(FALSE); assert(FALSE);
case ARGOFF: case ARGOFF:
@ -175,7 +153,8 @@ symvalue() {
case ARGUCN: case ARGUCN:
case ARGFCN: case ARGFCN:
if (ap->a_a.a_con.ac_length < wordsize) if (ap->a_a.a_con.ac_length < wordsize)
count = align(count,(offset)ap->a_a.a_con.ac_length); count = align(count,
(offset) ap->a_a.a_con.ac_length);
else else
count = align(count, wordsize); count = align(count, wordsize);
count += ap->a_a.a_con.ac_length; count += ap->a_a.a_con.ac_length;
@ -189,16 +168,62 @@ symvalue() {
} }
} }
do_tes() static void do_tes(void)
{ {
register line_p insptr = instrs, oldlin = NULL, oldlin2 = NULL; register line_p insptr = instrs, oldlin = NULL, oldlin2 = NULL;
init_state(); init_state();
tes_pseudos(); tes_pseudos();
while (insptr != NULL) { while (insptr != NULL)
{
tes_instr(insptr, oldlin, oldlin2); tes_instr(insptr, oldlin, oldlin2);
oldlin2 = oldlin; oldlin2 = oldlin;
oldlin = insptr; oldlin = insptr;
insptr = insptr->l_next; insptr = insptr->l_next;
} }
} }
void process(void)
{
if (wordsize == 0 || pointersize == 0)
error("No MES EMX encountered");
backward(); /* reverse and cleanup list */
symknown(); /* symbol scope is now known */
if (!nflag)
symvalue(); /* give symbols value */
if (prodepth != 0)
{
if (!nflag)
{
int npasses = 0;
bool madeopt;
checklocs(); /* check definition of locals */
do
{
madeopt = peephole(); /* local optimization */
relabel(); /* relabel local labels */
flow(); /* throw away unreachable code */
} while (madeopt && ++npasses < 5000);
assert(!madeopt);
}
do_tes(); /* top elt. size computation phase */
outpro(); /* generate PRO pseudo */
outregs(); /* generate MES ms_reg pseudos */
outtes(); /* generate MES ms_tes pseudos */
}
putlines(pseudos); /* pseudos first */
if (prodepth != 0)
{
putlines(instrs); /* instructions next */
outend(); /* generate END pseudo */
cleanlocals(); /* forget instruction labels */
}
else if (instrs != (line_p) 0)
error("instructions outside procedure");
#ifdef COREDEBUG
coreverbose();
#endif
}

View file

@ -1,8 +1,11 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h> #include <assert.h>
#include <stdlib.h>
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
#include "tes.h" #include "tes.h"
@ -12,30 +15,33 @@ static char rcsid[] = "$Id$";
#include <em_flag.h> #include <em_flag.h>
#include "alloc.h" #include "alloc.h"
#include "line.h" #include "line.h"
#include "putline.h"
#include "util.h"
#include "lookup.h" #include "lookup.h"
#include "proinf.h" #include "proinf.h"
#include "optim.h" #include "optim.h"
#include "ext.h" #include "ext.h"
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#define outbyte(b) putc(b,outfile) #define outbyte(b) putc(b,outfile)
putlines(lnp) register line_p lnp; { /* Forward declarations. */
static void numlab(register num_p);
static void putargs(register arg_p);
static void putstr(register argb_p);
void putlines(register line_p lnp)
{
register arg_p ap; register arg_p ap;
line_p temp; line_p temp;
register instr; register int instr;
short curlin = -2; short curlin = -2;
short thislin; short thislin;
while ( lnp != (line_p) 0) { while (lnp != (line_p) 0)
{
instr = lnp->l_instr & BMASK; instr = lnp->l_instr & BMASK;
switch(lnp->l_optyp) { switch (lnp->l_optyp)
{
case OPSYMBOL: case OPSYMBOL:
if ((lnp->l_instr & BMASK) == ps_sym) if ((lnp->l_instr & BMASK) == ps_sym)
outdef(lnp->l_a.la_sp); outdef(lnp->l_a.la_sp);
@ -52,8 +58,10 @@ putlines(lnp) register line_p lnp; {
#endif #endif
case OPLIST: case OPLIST:
ap = lnp->l_a.la_arg; ap = lnp->l_a.la_arg;
while (ap != (arg_p) 0) { while (ap != (arg_p) 0)
switch(ap->a_typ) { {
switch (ap->a_typ)
{
case ARGSYM: case ARGSYM:
outocc(ap->a_a.a_sp); outocc(ap->a_a.a_sp);
break; break;
@ -70,8 +78,8 @@ putlines(lnp) register line_p lnp; {
* global symbols now taken care of * global symbols now taken care of
*/ */
switch (instr)
switch(instr) { {
case ps_sym: case ps_sym:
break; break;
case op_lni: case op_lni:
@ -80,7 +88,8 @@ putlines(lnp) register line_p lnp; {
outinst(instr); outinst(instr);
break; break;
case op_lin: case op_lin:
switch(lnp->l_optyp) { switch (lnp->l_optyp)
{
case OPNO: case OPNO:
case OPOFFSET: case OPOFFSET:
case OPNUMLAB: case OPNUMLAB:
@ -97,13 +106,16 @@ putlines(lnp) register line_p lnp; {
thislin = (lnp->l_optyp & BMASK) - Z_OPMINI; thislin = (lnp->l_optyp & BMASK) - Z_OPMINI;
break; break;
} }
if (thislin == curlin && !nflag) { if (thislin == curlin && !nflag)
{
temp = lnp->l_next; temp = lnp->l_next;
oldline(lnp); oldline(lnp);
lnp = temp; lnp = temp;
OPTIM(O_LINGONE); OPTIM(O_LINGONE);
continue; continue;
} else if (thislin == curlin+1 && !nflag) { }
else if (thislin == curlin + 1 && !nflag)
{
instr = op_lni; instr = op_lni;
outinst(instr); outinst(instr);
temp = lnp->l_next; temp = lnp->l_next;
@ -112,7 +124,9 @@ putlines(lnp) register line_p lnp; {
lnp = newline(OPNO); lnp = newline(OPNO);
lnp->l_next = temp; lnp->l_next = temp;
lnp->l_instr = instr; lnp->l_instr = instr;
} else { }
else
{
outinst(instr); outinst(instr);
} }
curlin = thislin; curlin = thislin;
@ -125,8 +139,8 @@ putlines(lnp) register line_p lnp; {
curlin = -2; curlin = -2;
outinst(instr); outinst(instr);
} }
processoperand: processoperand: switch (lnp->l_optyp)
switch(lnp->l_optyp) { {
case OPNO: case OPNO:
if ((em_flag[instr - sp_fmnem] & EM_PAR) != PAR_NO) if ((em_flag[instr - sp_fmnem] & EM_PAR) != PAR_NO)
outbyte((byte) sp_cend); outbyte((byte) sp_cend);
@ -167,7 +181,8 @@ processoperand:
#endif #endif
case OPLIST: case OPLIST:
putargs(lnp->l_a.la_arg); putargs(lnp->l_a.la_arg);
switch(instr) { switch (instr)
{
case ps_con: case ps_con:
case ps_rom: case ps_rom:
case ps_mes: case ps_mes:
@ -187,12 +202,16 @@ processoperand:
} }
} }
putargs(ap) register arg_p ap; { static void putargs(register arg_p ap)
{
while (ap != (arg_p) 0) { while (ap != (arg_p) 0)
switch(ap->a_typ) { {
switch (ap->a_typ)
{
default: default:
assert(FALSE); assert(FALSE);
break;
case ARGOFF: case ARGOFF:
outoff(ap->a_a.a_offset); outoff(ap->a_a.a_offset);
break; break;
@ -219,8 +238,7 @@ putargs(ap) register arg_p ap; {
goto casecon; goto casecon;
case ARGFCN: case ARGFCN:
outbyte((byte) sp_fcon); outbyte((byte) sp_fcon);
casecon: casecon: outint(ap->a_a.a_con.ac_length);
outint(ap->a_a.a_con.ac_length);
putstr(&ap->a_a.a_con.ac_con); putstr(&ap->a_a.a_con.ac_con);
break; break;
} }
@ -228,25 +246,29 @@ putargs(ap) register arg_p ap; {
} }
} }
putstr(abp) register argb_p abp; { static void putstr(register argb_p abp)
{
register argb_p tbp; register argb_p tbp;
register length; register int length;
length = 0; length = 0;
tbp = abp; tbp = abp;
while (tbp!= (argb_p) 0) { while (tbp != (argb_p) 0)
{
length += tbp->ab_index; length += tbp->ab_index;
tbp = tbp->ab_next; tbp = tbp->ab_next;
} }
outint(length); outint(length);
while (abp != (argb_p) 0) { while (abp != (argb_p) 0)
{
for (length = 0; length < abp->ab_index; length++) for (length = 0; length < abp->ab_index; length++)
outbyte((byte ) abp->ab_contents[length]); outbyte((byte ) abp->ab_contents[length]);
abp = abp->ab_next; abp = abp->ab_next;
} }
} }
outdef(sp) register sym_p sp; { void outdef(register sym_p sp)
{
/* /*
* The surrounding If statement is removed to be friendly * The surrounding If statement is removed to be friendly
@ -255,7 +277,8 @@ outdef(sp) register sym_p sp; {
if ((sp->s_flags&SYMOUT)==0) { if ((sp->s_flags&SYMOUT)==0) {
*/ */
sp->s_flags |= SYMOUT; sp->s_flags |= SYMOUT;
if (sp->s_flags&SYMGLOBAL) { if (sp->s_flags & SYMGLOBAL)
{
outinst(sp->s_flags & SYMPRO ? ps_exp : ps_exa); outinst(sp->s_flags & SYMPRO ? ps_exp : ps_exa);
outsym(sp); outsym(sp);
} }
@ -264,44 +287,48 @@ outdef(sp) register sym_p sp; {
*/ */
} }
outocc(sp) register sym_p sp; { void outocc(register sym_p sp)
{
if ((sp->s_flags&SYMOUT)==0) { if ((sp->s_flags & SYMOUT) == 0)
{
sp->s_flags |= SYMOUT; sp->s_flags |= SYMOUT;
if ((sp->s_flags&SYMGLOBAL)==0) { if ((sp->s_flags & SYMGLOBAL) == 0)
{
outinst(sp->s_flags & SYMPRO ? ps_inp : ps_ina); outinst(sp->s_flags & SYMPRO ? ps_inp : ps_ina);
outsym(sp); outsym(sp);
} }
} }
} }
outpro() { void outpro(void)
{
outdef(curpro.symbol); outdef(curpro.symbol);
outinst(ps_pro); outinst(ps_pro);
outsym(curpro.symbol); outsym(curpro.symbol);
outoff(curpro.localbytes); outoff(curpro.localbytes);
} }
outend() { void outend(void)
{
outinst(ps_end); outinst(ps_end);
outoff(curpro.localbytes); outoff(curpro.localbytes);
} }
outinst(m) { void outinst(int m)
{
outbyte((byte ) m); outbyte((byte ) m);
} }
outoff(off) offset off; { void outoff(offset off)
{
#ifdef LONGOFF #ifdef LONGOFF
if ((short) off == off) if ((short) off == off)
#endif #endif
outint((short) off); outint((short) off);
#ifdef LONGOFF #ifdef LONGOFF
else { else
{
outbyte((byte) sp_cst4); outbyte((byte) sp_cst4);
outshort((short) (off & 0177777L)); outshort((short) (off & 0177777L));
outshort((short) (off >> 16)); outshort((short) (off >> 16));
@ -309,56 +336,71 @@ outoff(off) offset off; {
#endif #endif
} }
outint(i) short i; { void outint(short i)
{
if (i >= -sp_zcst0 && i < sp_ncst0 - sp_zcst0) if (i >= -sp_zcst0 && i < sp_ncst0 - sp_zcst0)
outbyte((byte) (i+sp_zcst0+sp_fcst0)); outbyte((byte) (i+sp_zcst0+sp_fcst0));
else { else
{
outbyte((byte) sp_cst2); outbyte((byte) sp_cst2);
outshort(i); outshort(i);
} }
} }
outshort(i) short i; { void outshort(short i)
{
outbyte((byte) (i&BMASK)); outbyte((byte) (i&BMASK));
outbyte((byte ) (i >> 8)); outbyte((byte ) (i >> 8));
} }
numlab(np) register num_p np; { static void numlab(register num_p np)
{
if (np->n_number < sp_nilb0) if (np->n_number < sp_nilb0)
outbyte((byte) (np->n_number + sp_filb0)); outbyte((byte) (np->n_number + sp_filb0));
else else
outnum(np); outnum(np);
} }
outnum(np) register num_p np; { void outnum(register num_p np)
{
if(np->n_number<256) { if (np->n_number < 256)
{
outbyte((byte) sp_ilb1); outbyte((byte) sp_ilb1);
outbyte((byte ) (np->n_number)); outbyte((byte ) (np->n_number));
} else { }
else
{
outbyte((byte) sp_ilb2); outbyte((byte) sp_ilb2);
outshort((short) np->n_number); outshort((short) np->n_number);
} }
} }
outsym(sp) register sym_p sp; { void outsym(register sym_p sp)
register byte *p; {
register char *p;
register unsigned num; register unsigned num;
if (sp->s_name[0] == '.') { if (sp->s_name[0] == '.')
{
num = atoi(&sp->s_name[1]); num = atoi(&sp->s_name[1]);
if (num < 256) { if (num < 256)
{
outbyte((byte) sp_dlb1); outbyte((byte) sp_dlb1);
outbyte((byte ) (num)); outbyte((byte ) (num));
} else { }
else
{
outbyte((byte) sp_dlb2); outbyte((byte) sp_dlb2);
outshort((short) num); outshort((short) num);
} }
} else { }
else
{
p = sp->s_name; p = sp->s_name;
/* This is not a real warning, because s_name is dynamically
* allocated as necessary.
*/
while (*p && p < &sp->s_name[IDL]) while (*p && p < &sp->s_name[IDL])
p++; p++;
num = p - sp->s_name; num = p - sp->s_name;

25
util/opt/putline.h Normal file
View file

@ -0,0 +1,25 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-04-06
*
*/
#ifndef PUTLINE_H_
#define PUTLINE_H_
#include "types.h"
void putlines(register line_p lnp);
void outdef(register sym_p sp);
void outocc(register sym_p sp);
void outpro(void);
void outend(void);
void outinst(int m);
void outoff(offset off);
void outint(short i);
void outshort(short i);
void outnum(register num_p np);
void outsym(register sym_p sp);
#endif /* PUTLINE_H_ */

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <assert.h> #include <assert.h>
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
@ -9,45 +11,50 @@ static char rcsid[] = "$Id$";
#include "tes.h" #include "tes.h"
#include "proinf.h" #include "proinf.h"
#include "alloc.h" #include "alloc.h"
#include "putline.h"
#include "reg.h"
#include <em_spec.h> #include <em_spec.h>
#include <em_pseu.h> #include <em_pseu.h>
#include <em_mes.h> #include <em_mes.h>
#include "ext.h" #include "ext.h"
/* void regvar(register arg_p ap)
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. {
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
void
regvar(ap) register arg_p ap; {
register reg_p rp; register reg_p rp;
register i; register int i;
rp = newreg(); rp = newreg();
i = 0; i = 0;
while (ap!=(arg_p)0 && ap->a_typ==ARGOFF && i<4) { while (ap != (arg_p) 0 && ap->a_typ == ARGOFF && i < 4)
{
rp->r_par[i++] = ap->a_a.a_offset; rp->r_par[i++] = ap->a_a.a_offset;
ap = ap->a_next; ap = ap->a_next;
} }
/* /*
* Omit incomplete messages * Omit incomplete messages
*/ */
switch(i) { switch (i)
default:assert(FALSE); {
default:
assert(FALSE);
break;
case 0: case 0:
case 1: case 1:
case 2: oldreg(rp); return; case 2:
case 3: rp->r_par[3]= (offset) 0; break; oldreg(rp);
case 4: break; return;
case 3:
rp->r_par[3] = (offset) 0;
break;
case 4:
break;
} }
rp->r_next = curpro.freg; rp->r_next = curpro.freg;
curpro.freg = rp; curpro.freg = rp;
} }
inreg(off) offset off; { int inreg(offset off)
{
register reg_p rp; register reg_p rp;
for (rp = curpro.freg; rp != (reg_p) 0; rp = rp->r_next) for (rp = curpro.freg; rp != (reg_p) 0; rp = rp->r_next)
@ -56,11 +63,13 @@ inreg(off) offset off; {
return (FALSE); return (FALSE);
} }
outregs() { void outregs(void)
{
register reg_p rp, tp; register reg_p rp, tp;
register i; register int i;
for(rp=curpro.freg; rp != (reg_p) 0; rp = tp) { for (rp = curpro.freg; rp != (reg_p) 0; rp = tp)
{
tp = rp->r_next; tp = rp->r_next;
outinst(ps_mes); outinst(ps_mes);
outoff((offset) ms_reg); outoff((offset) ms_reg);
@ -80,13 +89,17 @@ outregs() {
} }
/* outtes() handles the output of the top elt. messages */ /* outtes() handles the output of the top elt. messages */
outtes() { void outtes(void)
{
register num_p *npp, np; register num_p *npp, np;
for (npp=curpro.numhash;npp< &curpro.numhash[NNUMHASH]; npp++) { for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np=np->n_next) { {
if (! (np->n_flags & NUMSET) || np->n_size == 0 || for (np = *npp; np != (num_p) 0; np = np->n_next)
(np->n_flags & NUMCOND)) continue; {
if (!(np->n_flags & NUMSET) || np->n_size == 0
|| (np->n_flags & NUMCOND))
continue;
outinst(ps_mes); outinst(ps_mes);
outoff((offset) ms_tes); outoff((offset) ms_tes);
outoff((offset) np->n_number); outoff((offset) np->n_number);
@ -97,8 +110,8 @@ outtes() {
} }
} }
void void incregusage(offset off)
incregusage(off) offset off; { {
register reg_p rp; register reg_p rp;
#ifndef GLOBAL_OPT #ifndef GLOBAL_OPT
@ -106,7 +119,8 @@ incregusage(off) offset off; {
* we must not change the count fields of the register messages. * we must not change the count fields of the register messages.
*/ */
for (rp = curpro.freg; rp != (reg_p) 0; rp = rp->r_next) for (rp = curpro.freg; rp != (reg_p) 0; rp = rp->r_next)
if (rp->r_par[0]==off) { if (rp->r_par[0] == off)
{
rp->r_par[3]++; rp->r_par[3]++;
return; return;
} }

17
util/opt/reg.h Normal file
View file

@ -0,0 +1,17 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
*/
#ifndef REG_H_
#define REG_H_
#include "types.h"
void regvar(register arg_p ap);
void outregs(void);
int inreg(offset off);
void outtes(void);
void incregusage(offset off);
#endif /* REG_H_ */

View file

@ -1,8 +1,4 @@
%{ %{
#ifndef NORCSID
static char rcsid2[] = "$Id$";
#endif
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
@ -13,6 +9,8 @@ static char rcsid2[] = "$Id$";
extern long atol(); extern long atol();
extern char patid[128]; extern char patid[128];
extern int lino; extern int lino;
extern int mlookup(char* name);
extern void yyerror(const char *);
#include "y.tab.h" #include "y.tab.h"

View file

@ -1,22 +1,15 @@
#ifndef NORCSID
static char rcsid[] = "$Id$";
#endif
#include "param.h"
#include "types.h"
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
* *
* Author: Hans van Staveren * Author: Hans van Staveren
*/ */
#include "param.h"
#include "types.h"
#ifdef ALLOWSPECIAL #ifdef ALLOWSPECIAL
bool special(lpp,bp,patlen) bool special(line_p *lpp,byte *bp,int patlen)
line_p *lpp;
byte *bp;
int patlen;
{ {
return(FALSE); return(FALSE);

View file

@ -1,12 +1,8 @@
#ifndef NORCSID
static char rcsid[] = "$Id$";
#endif
/* /*
* This file contains the main part of the top element size computation phase. * This file contains the main part of the top element size computation phase.
* *
* Author: Hans van Eck. * Author: Hans van Eck.
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <em_spec.h> #include <em_spec.h>
@ -39,97 +35,136 @@ extern char flow_tab[];
int state; int state;
static int stacktop = 0; static int stacktop = 0;
init_state() /* Forward declarations */
static void do_inst_label(line_p);
static void assign_label(register num_p);
void init_state(void)
{ {
stacktop = 0; stacktop = 0;
state = KNOWN; state = KNOWN;
} }
tes_pseudos() void tes_pseudos(void)
{ {
register line_p lp; register line_p lp;
for (lp = pseudos; lp != (line_p)0; lp = lp->l_next) { for (lp = pseudos; lp != (line_p) 0; lp = lp->l_next)
switch(INSTR(lp)) { {
switch (INSTR(lp))
{
case ps_con: case ps_con:
case ps_rom: case ps_rom:
if (lp->l_optyp == OPLIST) { if (lp->l_optyp == OPLIST)
{
register arg_p ap = lp->l_a.la_arg; register arg_p ap = lp->l_a.la_arg;
while (ap != (arg_p) 0) { while (ap != (arg_p) 0)
if (ap->a_typ == ARGNUM) { {
if (ap->a_typ == ARGNUM)
{
assign_label(ap->a_a.a_np->n_repl); assign_label(ap->a_a.a_np->n_repl);
} }
ap = ap->a_next; ap = ap->a_next;
} }
} else if (lp->l_optyp == OPNUMLAB) }
else if (lp->l_optyp == OPNUMLAB)
assign_label(lp->l_a.la_np->n_repl); assign_label(lp->l_a.la_np->n_repl);
} }
} }
} }
void void tes_instr(line_p lnp, line_p x, line_p y)
tes_instr(lnp, x, y)
line_p lnp, x, y;
{ {
char *s; char *s;
register instr = INSTR(lnp); register int instr = INSTR(lnp);
register int arg, argdef; register int arg, argdef;
int neg = 0; int neg = 0;
if (instr == op_lab) { if (instr == op_lab)
{
do_inst_label(lnp); do_inst_label(lnp);
return; return;
} }
if (instr < sp_fmnem || instr > sp_lmnem) { if (instr < sp_fmnem || instr > sp_lmnem)
{
return; return;
} }
if (state == NOTREACHED) return; /* What else ? */ if (state == NOTREACHED)
return; /* What else ? */
s = pop_push[instr]; s = pop_push[instr];
if (*s != '0') { if (*s != '0')
while (*s != '\0') { {
while (*s != '\0')
{
neg = (*s++ == '-'); neg = (*s++ == '-');
if (TYPE(lnp) == OPSHORT) { if (TYPE(lnp) == OPSHORT)
{
arg = SHORT(lnp); arg = SHORT(lnp);
if (arg < wordsize) arg = wordsize; if (arg < wordsize)
arg = wordsize;
argdef = TRUE; argdef = TRUE;
} else if (IS_MINI(lnp)) { }
else if (IS_MINI(lnp))
{
arg = MINI(lnp); arg = MINI(lnp);
if (arg > 0 && arg < wordsize) arg = wordsize; if (arg > 0 && arg < wordsize)
if (arg < 0 && -arg < wordsize) arg = -wordsize; arg = wordsize;
if (arg < 0 && -arg < wordsize)
arg = -wordsize;
argdef = TRUE; argdef = TRUE;
} else { }
else
{
argdef = FALSE; argdef = FALSE;
} }
switch (*s++) { switch (*s++)
case 'w': stacktop = wordsize; break; {
case 'd': stacktop = wordsize * 2; break; case 'w':
case 'p': stacktop = pointersize; break; stacktop = wordsize;
break;
case 'd':
stacktop = wordsize * 2;
break;
case 'p':
stacktop = pointersize;
break;
case 'a': case 'a':
if (argdef == FALSE || instr == op_ass) { if (argdef == FALSE || instr == op_ass)
{
stacktop = 0; stacktop = 0;
} else { }
else
{
stacktop = arg; stacktop = arg;
} }
break; break;
case 'x': case 'x':
if (IS_LOC(x)) { if (IS_LOC(x))
{
arg = MINI(x); arg = MINI(x);
if (arg < wordsize) arg = wordsize; if (arg < wordsize)
arg = wordsize;
stacktop = arg; stacktop = arg;
} else { }
else
{
stacktop = 0; stacktop = 0;
} }
break; break;
case 'y': case 'y':
if (IS_LOC(y)) { if (IS_LOC(y))
{
arg = MINI(y); arg = MINI(y);
if (arg < wordsize) arg = wordsize; if (arg < wordsize)
arg = wordsize;
stacktop = arg; stacktop = arg;
} else { }
else
{
stacktop = 0; stacktop = 0;
} }
break; break;
@ -144,47 +179,62 @@ line_p lnp, x, y;
* When the last argument was negative, the element size * When the last argument was negative, the element size
* must be negated. This is to catch 'asp -4'. * must be negated. This is to catch 'asp -4'.
*/ */
if (neg) stacktop = -stacktop; if (neg)
stacktop = -stacktop;
} }
if (stacktop < 0) stacktop = 0; if (stacktop < 0)
stacktop = 0;
if (ISABRANCH(instr)) do_inst_label(lnp); if (ISABRANCH(instr))
if (NON_CONTINUABLE(instr)) { do_inst_label(lnp);
if (NON_CONTINUABLE(instr))
{
state = NOTREACHED; state = NOTREACHED;
stacktop = 0; stacktop = 0;
} }
} }
assign_label(label) static void assign_label(register num_p label)
register num_p label; {
if (label->n_flags & NUMSET)
{
if (state == NOTREACHED || stacktop > label->n_size)
{ {
if (label->n_flags & NUMSET) {
if (state == NOTREACHED || stacktop > label->n_size) {
stacktop = label->n_size; stacktop = label->n_size;
} else if ( stacktop < label->n_size) { }
else if (stacktop < label->n_size)
{
label->n_size = stacktop; label->n_size = stacktop;
} }
} else { }
else
{
label->n_size = stacktop; label->n_size = stacktop;
label->n_flags |= NUMSET; label->n_flags |= NUMSET;
} }
} }
do_inst_label(lnp) /* (re-)install a label */ /* (re-)install a label */
line_p lnp; static void do_inst_label(line_p lnp)
{ {
num_p label = lnp->l_a.la_np->n_repl; num_p label = lnp->l_a.la_np->n_repl;
int instr = INSTR(lnp); int instr = INSTR(lnp);
assign_label(label); assign_label(label);
if (instr == op_lab) { if (instr == op_lab)
if (state == NOTREACHED) { {
} else { if (state == NOTREACHED)
{
}
else
{
label->n_flags |= NUMFALLTHROUGH; label->n_flags |= NUMFALLTHROUGH;
} }
} else if (ISCONDBRANCH(instr)) { /* conditional branch */ }
else if (ISCONDBRANCH(instr))
{ /* conditional branch */
label->n_flags |= NUMCOND; label->n_flags |= NUMCOND;
} }
state = KNOWN; state = KNOWN;

View file

@ -1,8 +1,17 @@
/* /*
* Author: Hans van Eck. * Author: Hans van Eck.
*/ */
/* $Id$ */ #ifndef TES_H_
#define TES_H_
#include "types.h"
extern int state; extern int state;
#define KNOWN 1 #define KNOWN 1
#define NOTREACHED 2 #define NOTREACHED 2
void init_state(void);
void tes_pseudos(void);
void tes_instr(line_p lnp, line_p x, line_p y);
#endif /* TES_H_ */

View file

@ -2,9 +2,10 @@
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
*/ */
/* $Id$ */ #ifndef TYPES_H_
#define TYPES_H_
typedef char byte; typedef unsigned char byte;
typedef char bool; typedef char bool;
typedef struct line line_t; typedef struct line line_t;
typedef struct line *line_p; typedef struct line *line_p;
@ -23,3 +24,5 @@ typedef long offset;
#else #else
typedef short offset; typedef short offset;
#endif #endif
#endif /* TYPES_H_ */

View file

@ -1,43 +1,44 @@
#ifndef NORCSID
static char rcsid[] = "$Id$";
#endif
#include <stdlib.h>
#include <stdio.h>
#include "param.h"
#include "types.h"
#include "tes.h"
#include "lookup.h"
#include "proinf.h"
#include "optim.h"
#include "ext.h"
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright". * See the copyright notice in the ACK home directory, in the file "Copyright".
* *
* Author: Hans van Staveren * Author: Hans van Staveren
*/ */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "param.h"
#include "types.h"
#include "tes.h"
#include "lookup.h"
#include "proinf.h"
#include "optim.h"
#include "util.h"
#include "ext.h"
/* VARARGS1 */ /* VARARGS1 */
error(s,a) char *s,*a; { void error(char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "%s: error on line %u", progname, linecount); fprintf(stderr, "%s: error on line %u", progname, linecount);
if (prodepth != 0) if (prodepth != 0)
fprintf(stderr, "(%.*s)", IDL, curpro.symbol->s_name); fprintf(stderr, "(%.*s)", IDL, curpro.symbol->s_name);
fprintf(stderr, ": "); fprintf(stderr, ": ");
fprintf(stderr,s,a); vfprintf(stderr, s, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(ap);
#ifndef NDEBUG #ifndef NDEBUG
abort(); abort();
#endif #endif
exit(-1); exit(EXIT_FAILURE);
} }
#ifdef DIAGOPT #ifdef DIAGOPT
optim(n) { void optim(int n)
{
fprintf(stderr,"Made optimization %d",n); fprintf(stderr,"Made optimization %d",n);
if (prodepth) if (prodepth)
fprintf(stderr," (%.*s)",IDL,curpro.symbol->s_name); fprintf(stderr," (%.*s)",IDL,curpro.symbol->s_name);

15
util/opt/util.h Normal file
View file

@ -0,0 +1,15 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
*
*/
#ifndef UTIL_H_
#define UTIL_H_
void error(char *s, ...);
#ifdef DIAGOPT
void optim(int n);
#endif
#endif /* UTIL_H_ */

View file

@ -1,7 +1,9 @@
#ifndef NORCSID /*
static char rcsid[] = "$Id$"; * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
#endif * See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
#include <stdio.h> #include <stdio.h>
#include "param.h" #include "param.h"
#include "types.h" #include "types.h"
@ -9,12 +11,7 @@ static char rcsid[] = "$Id$";
#include "lookup.h" #include "lookup.h"
#include "proinf.h" #include "proinf.h"
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Staveren
*/
unsigned linecount = 0; /* "line"number for errormessages */ unsigned linecount = 0; /* "line"number for errormessages */
int prodepth = 0; /* Level of nesting */ int prodepth = 0; /* Level of nesting */
@ -25,7 +22,7 @@ bool repl_longmuls = 0; /* replacing longmuls as well? */
line_p instrs,pseudos; /* pointers to chains */ line_p instrs,pseudos; /* pointers to chains */
sym_p symhash[NSYMHASH]; /* array of pointers to chains */ sym_p symhash[NSYMHASH]; /* array of pointers to chains */
FILE *outfile; FILE *outfile;
char template[] = "/tmp/emoptXXXXXX"; char tempname[L_tmpnam];
offset wordsize = 0; offset wordsize = 0;
offset pointersize = 0; offset pointersize = 0;
char *progname; char *progname;