Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,917 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* canon - expression canonicalization*/
/* Top level tree canonicalization. This fixes any bit field*/
/* accesses, then loops on commute and optim until no more*/
/* optimizations are done.*/
char *canon(tp) /* returns pointer to tree*/
struct tnode *tp; /* pointer to tree to canonicalize*/
{
tp = fixbfield(tp);
do {
sucomp(tp,0,1); /*need Sethy-Ullman's for commute*/
tp = commute(tp); /*commute the tree*/
} while( optim(&tp) ); /*keep trying for optimizations*/
#ifndef NODEBUG
if( oflag )
putexpr("canon",tp);
#endif
return(tp);
}
/* fixbfield - fix bit field operators*/
/* Fixes bit field assignment and normal usage*/
char *fixbfield(tp) /* returns pointer to fixed tree*/
struct tnode *tp; /* pointer to tree*/
{
register struct tnode *btp, *stp;
register int foff, fmask, op, flen;
if( leafop(op=tp->t_op) )
return(tp);
if( asgop(op) && tp->t_left->t_op == BFIELD ) {
btp = tp->t_left; /*pointer to BFIELD node*/
stp = btp->t_left; /*pointer to son of BFIELD node*/
foff = (btp->t_su>>8) & 0377;
flen = btp->t_su & 0377;
fmask = (1<<flen)-1;
if( tp->t_right->t_op == CINT && (op == ASSIGN || op == EQXOR) ) {
if( op == EQXOR ) {
tp->t_left = stp;
tp->t_right->t_value =<< foff;
return(tp);
}
if( tp->t_right->t_value == 0 ) {
tp->t_op = EQAND;
tp->t_left = stp;
tp->t_right->t_value = ~ (fmask << foff);
return(tp);
}
if( (tp->t_right->t_value & fmask) == fmask ) {
tp->t_op = EQOR;
tp->t_left = stp;
tp->t_right->t_value = fmask << foff;
return(tp);
}
}
if( fmask == -1 )
tp->t_left = stp;
else {
stp = tcopy(stp);
btp = fixbfield(btp);
op = tp->t_op;
tp = tp->t_right; /*pointer to expression*/
if( op != ASSIGN ) /*=op operator?*/
tp = tnalloc(op-(EQADD-ADD),INT,0,0,btp,tp);
tp = tnalloc(AND,INT,0,0,tp,cnalloc(INT,fmask));
tp = tnalloc(LSH,INT,0,0,tp,cnalloc(INT,foff));
btp = tnalloc(AND,INT,0,0,tcopy(stp),
cnalloc(INT,~(fmask<<foff)));
tp = tnalloc(OR,INT,0,0,btp,tp);
tp = tnalloc(ASSIGN,INT,0,0,stp,tp);
}
}
else if( op == BFIELD ) {
foff = (tp->t_su>>8) & 0377;
fmask = (1<<(tp->t_su&0377))-1;
tp = tnalloc(RSH,INT,0,0,tp->t_left,cnalloc(INT,foff));
tp = tnalloc(AND,INT,0,0,tp,cnalloc(INT,fmask));
}
else {
tp->t_left = fixbfield(tp->t_left);
if( binop(op) )
tp->t_right = fixbfield(tp->t_right);
}
return(tp);
}
/* optim - optimize expression tree*/
/* This takes expression tree and performs the following*/
/* translations: folds auto names to accesses off the local*/
/* environment pointer, performs mostly "machine-independent"*/
/* optimizations, such as multiply by zero and one, etc.,*/
/* turns field accesses into and's and or's, etc.*/
optim(tpp) /* returns pointer to new tree*/
struct tnode **tpp;
{
register struct tnode *ltp, *rtp, *tp;
register char *p;
register int i, cval, changes, op;
tp = *tpp;
if( tp->t_type & ~TYPE ) {
tp->t_type =& TYPE;
tp->t_type =| POINTER;
}
if( leafop(op=tp->t_op) )
return(0);
changes = 0;
if( binop(op) )
changes =+ optim(&tp->t_right);
changes =+ optim(&tp->t_left);
for( ; notleafop(op=tp->t_op); changes++ ) {
#ifndef NODEBUG
if( oflag )
putexpr("optim",tp);
#endif
*tpp = tp;
ltp = tp->t_left;
if( binop(op) ) {
rtp = tp->t_right;
if( tp->t_type == CHAR )
tp->t_type = INT;
p = constant(rtp);
}
else
p = constant(ltp);
ltp = tp->t_left;
if( p )
cval = p->t_value;
switch( op ) {
case ADD:
if( p ) {
if( cval == 0 ) {
tp = ltp;
continue;
}
if( ltp->t_op == ADDR ) {
ltp->t_left->t_offset =+ cval;
tp = ltp;
continue;
}
}
break;
case ASSIGN:
if( rtp->t_op == ADD && indexreg(rtp->t_left) &&
rtp->t_right->t_op == CINT ) {
ltp = rtp->t_left;
ltp->t_sc = REGOFF;
ltp->t_offset =+ rtp->t_right->t_value;
tp->t_right = ltp;
tp->t_op = EQADDR;
continue;
}
break;
case SUB:
if( p ) {
if( cval == 0 ) {
tp = ltp;
continue;
}
tp->t_op = ADD;
p->t_value = -cval;
continue;
}
if( (p=constant(ltp)) && p->t_value == 0 ) { /*0-X=-X*/
tp->t_op = UMINUS;
tp->t_left = ltp = rtp;
continue;
}
break;
case DIV:
case EQDIV:
if( p ) {
if( cval == 0 ) { /*X/0->error*/
error("divide by zero");
tp = rtp;
continue;
}
if( cval == 1 ) {
tp = ltp;
continue;
}
if( cval == -1 && op == DIV ) {
tp->t_op = UMINUS;
continue;
}
}
if( (p=constant(ltp)) && p->t_value == 0 ) {
tp = ltp;
continue;
}
if( multop(tpp) ) {
tp = *tpp;
continue;
}
break;
case EQMOD:
case MOD:
if( p ) {
if( cval == 0 ) { /*X%0->error*/
error("modulus by zero");
tp = rtp;
continue;
}
if( cval == 1 ) { /*X%1->0*/
p->t_value = 0;
tp = rtp;
continue;
}
}
if( (p=constant(ltp)) && p->t_value == 0 ) {
tp = ltp;
continue;
}
if( multop(tpp) ) {
tp = *tpp;
continue;
}
break;
case MULT:
case EQMULT:
if( p ) {
if( cval == 0 ) {
tp = rtp;
continue;
}
if( cval == 1 ) {
tp = ltp;
continue;
}
if( cval == -1 && op == MULT ) {
tp->t_op = UMINUS;
continue;
}
}
if( multop(tpp) ) {
tp = *tpp;
continue;
}
break;
case EQUALS:
case NEQUALS:
if( p && (i=onebit(cval)) >= 0 && ltp->t_op == AND &&
(rtp=constant(ltp->t_right)) &&
i == onebit(rtp->t_value) ) {
tp->t_op = invrel[tp->t_op-EQUALS];
p->t_value = 0;
continue;
}
break;
case GREATEQ:
if( p && cval == 0 && unsign(ltp->t_type) ) {
p->t_value = 1;
tp = p;
continue;
}
break;
case LESS:
if( p && cval == 0 && unsign(ltp->t_type) ) {
tp = p;
continue;
}
break;
case AND:
if( p ) {
if( cval == 0 ) {
tp = rtp;
continue;
}
if( cval == -1 ) {
tp = ltp;
continue;
}
}
break;
case OR:
if( p ) {
if( cval == 0 ) {
tp = ltp;
continue;
}
if( cval == -1 ) {
tp = rtp;
continue;
}
}
break;
case XOR:
if( p ) {
if( cval == 0 ) {
tp = ltp;
continue;
}
if( cval == -1 ) {
tp->t_op = COMPL;
continue;
}
}
break;
case LSH:
case EQLSH:
if( tp->t_type == LONG && rtp->t_op == INT2L &&
unsign(rtp->t_left) ) {
tp->t_right = rtp->t_left;
continue;
}
case RSH:
case EQRSH:
if( p ) {
if( cval == 0 ) {
tp = ltp;
continue;
}
if( p != rtp ) {
tp->t_right = p;
continue;
}
}
break;
case ADDR:
if( ltp->t_op == INDR ) {
tp = ltp->t_left;
continue;
}
if( ltp->t_op == SYMBOL && ltp->t_sc == REGOFF ) {
tp->t_op = ADD;
tp->t_right = cnalloc(INT,ltp->t_offset);
ltp->t_type = tp->t_type;
ltp->t_sc = REGISTER;
ltp->t_offset = 0;
continue;
}
break;
case INDR:
p = ltp->t_left;
switch( ltp->t_op ) {
case ADDR:
tp = p;
continue;
case CINT:
tp = snalloc(tp->t_type,CINDR,ltp->t_value,0,0);
continue;
case CLONG:
tp = snalloc(tp->t_type,CLINDR,ltp->t_lvalue.hiword,0,
ltp->t_lvalue.loword);
continue;
case SYMBOL:
if( indexreg(ltp) ) {
ltp->t_sc = REGOFF;
ltp->t_type = tp->t_type;
ltp->t_offset = 0;
tp = ltp;
continue;
}
break;
case ADD:
if( p->t_op == SYMBOL && p->t_sc == REGOFF &&
(rtp=constant(ltp->t_right)) &&
notpointer(p->t_type) ) {
p->t_offset =+ rtp->t_value;
tp = p;
continue;
}
if( indexreg(p) ) {
if( rtp = constant(ltp->t_right) ) {
/*This combines an address register and a constant into a register*/
/*offset. This relies on 68000 Addressing scheme somewhat.*/
p->t_sc = REGOFF;
p->t_type = tp->t_type;
p->t_offset =+ rtp->t_value;
tp = p;
continue;
}
if( lflag == 0 && ltp->t_right->t_op == ADDR ) {
/*We can fold *(An+&expr) into *(&expr(An)), but note that &expr*/
/*must be 16 bits for 68000, hence we can only do this if short*/
/*addresses are enabled. Note that the storage classes are mapped:*/
/*EXTERNAL->EXTOFF, STATIC->STATOFF, REGISTER->REGOFF*/
ltp = ltp->t_right->t_left;
ltp->t_sc =+ (EXTOFF-EXTERNAL);
ltp->t_type = tp->t_type;
tp = ltp;
continue;
}
}
break;
/*--X and X++ can be folded into -(An) and (An)+ 68000 instructions*/
case PREDEC:
case POSTINC:
if( indexreg(p) && ltp->t_type == p->t_type ) {
p->t_op = (ltp->t_op == PREDEC ? AUTODEC : AUTOINC);
p->t_type = tp->t_type;
tp = p;
continue;
}
}
break;
case NOT:
if( relop(ltp->t_op) ) { /*!(X>Y)->X<=Y*/
tp = ltp;
tp->t_op = invrel[tp->t_op-EQUALS];
continue;
}
break;
case UMINUS:
case COMPL:
if( tp->t_type == CHAR )
tp->t_type = INT;
if( tp->t_op == ltp->t_op ) {
tp = ltp->t_left;
continue;
}
if( ltp->t_op == INT2L ) { /*~(INT2L X)->INT2L (~X)*/
ltp->t_op = tp->t_op;
tp->t_op = INT2L;
ltp->t_type = INT;
continue;
}
break;
case INT2L:
if( ltp->t_op == MULT ) { /*INT2L (X*Y)->X*Y*/
ltp->t_type = (ltp->t_type&(~TYPE))|LONG;
tp = ltp;
continue;
}
break;
}
if( ccexpr(tpp) == 0 )
break;
tp = *tpp;
}
*tpp = tp;
return(changes);
}
/* commute - commutes expression tree to canonical form*/
/* This sorts commutable expression trees so that the most*/
/* difficult expression is the left-most operand. Note that*/
/* canon assumes that commute has placed constant operands in*/
/* the right sub-tree. This also swaps relationals so that the*/
/* most difficult expression is on the left.*/
char *commute(tp) /* returns commuted expression tree*/
struct tnode *tp;
{
struct tnode *clist[20], *plist[19];
register struct tnode **p, **q, *s;
struct tnode **plp, **clp;
register int op;
if( relop(op=tp->t_op) ) {
s = tp->t_left;
if( harder(tp->t_right,s) ) {
#ifndef NODEBUG
if(oflag)
putexpr("swaprel",tp);
#endif
tp->t_op = swaprel[op-EQUALS];
tp->t_left = tp->t_right;
tp->t_right = s;
}
}
if( commop(op) ) {
#ifndef NODEBUG
if(oflag)
putexpr("commute",tp);
#endif
clp = clist;
plp = plist;
addtree(tp,&clp,&plp); /*collect comm. expressions*/
/*see if any sub-trees can also be commuted (with different operator)*/
clp--;
plp--;
for( p = clist; p <= clp; p++ )
*p = commute(*p);
/*this sorts the expressions in decreasing order of Sethy-Ullman*/
/*values.*/
for( p = clist; p <= clp; p++ ) {
for( q = p; q <= clp; q++ ) {
if( harder(*q,*p) ) {
s = *q;
*q = *p;
*p = s;
}
}
}
/*Now, we start at the end of the list and collect any constants*/
/*if possible.*/
for( q = clp, p = plp; p > plist; p-- ) {
s = *p;
s->t_right = *q;
s->t_left = *--q;
if( ccexpr(p) ) {
clp--;
plp--;
}
}
/*this takes the sorted sub-expression pointers and the pointers*/
/*to the commutable operator nodes (plist) and structures the*/
/*tree so that the left sub-expression is the most complex. The*/
/*code generation scheme is very sensitive to this...*/
q = clist;
p = plist;
s = *q++;
while( p <= plp ) {
(*p)->t_left = s;
s = *p++;
s->t_right = *q++;
if( longorptr(s->t_type) == 0 ) {
if( longorptr(s->t_right->t_type) )
s->t_type = s->t_right->t_type;
else if( longorptr(s->t_left->t_type) )
s->t_type = s->t_left->t_type;
}
}
tp = s;
#ifndef NODEBUG
if(oflag)
putexpr("after commute",tp);
#endif
}
else if( binop(op) ) {
tp->t_left = commute(tp->t_left);
tp->t_right = commute(tp->t_right);
}
else if( unaryop(op) )
tp->t_left = commute(tp->t_left);
return(tp);
}
/* harder - test one sub-expression for being "harder" than another*/
/* This requires some special finagling for registers. The reason*/
/* for this is that the code skeletons produce better code if the*/
/* register is on the left. Also note that allowing an address*/
/* register on the right can have disastrous effects for AND and OR.*/
/* The basic point is: don't mess with this routine unless you're*/
/* 100% sure you understand the ramifications...*/
harder(tp,ntp) /* returns 1 if tp > ntp, else 0*/
struct tnode *tp;
struct tnode *ntp;
{
if( ntp->t_su == SU_VHARD )
return(0);
if( tp->t_su == SU_VHARD )
return(1);
if( isreg(ntp) )
return(0);
if( isreg(tp) )
return(1);
if( constant(ntp) )
return(1);
if( constant(tp) )
return(0);
return( tp->t_su > ntp->t_su );
}
/* addtree - collect commutable sub-trees for commute*/
/* This recurses down the sub-trees looking for groups of*/
/* commutable operators. It collects the sub-trees and their*/
/* parent nodes for commute.*/
addtree(tp,clist,plist) /* returns pointer to clist*/
struct tnode *tp; /* pointer to tree*/
struct tnode ***clist; /* commutable sub-trees*/
struct tnode ***plist; /* parent nodes of sub-trees*/
{
register struct tnode ***p, ***c;
c = clist;
p = plist;
if( tp->t_op == tp->t_left->t_op )
addtree(tp->t_left,c,p);
else
*(*c)++ = tp->t_left;
if( tp->t_op == tp->t_right->t_op )
addtree(tp->t_right,c,p);
else
*(*c)++ = tp->t_right;
*(*p)++ = tp;
}
/* constant - test for tree being a constant node*/
char *constant(tp) /* returns 0 or ptr to const node*/
struct tnode *tp; /* pointer to tree*/
{
if( tp->t_op == CINT )
return(tp);
if( tp->t_op == INT2L && tp->t_left->t_op == CINT )
return(tp->t_left);
return(0);
}
/* indexreg - returns whether node is an address register*/
/* For 68000, must be an A register*/
indexreg(tp) /* returns whether node is A reg*/
struct tnode *tp; /* pointer to tree*/
{
if( tp->t_op == SYMBOL && tp->t_sc == REGISTER &&
isdreg(tp->t_reg) == 0 )
return(1);
return(0);
}
/* ccexpr - compute constant expression*/
/* Evaluates constant expressions, including ?: and relationals*/
ccexpr(tpp) /* returns 1 if changes, 0 otherwise*/
struct tnode **tpp; /* pointer to tree*/
{
register struct tnode *ltp, *rtp, *tp;
register int op, i, j, anylong;
register long rval, lval;
tp = *tpp;
op = tp->t_op;
if( leafop(op) )
return(0);
anylong = 0;
ltp = tp->t_left;
if( ltp->t_op == CLONG ) {
lval = ltp->t_lvalue;
anylong++;
}
else if( ltp = constant(ltp) )
lval = ltp->t_value;
else
return(0);
if( binop(op) ) {
rtp = tp->t_right;
if( op == QMARK ) {
ltp = rtp->t_left;
rtp = rtp->t_right;
if( ltp->t_op != CINT || rtp->t_op != CINT )
return(0);
ltp->t_value = (lval?ltp->t_value:rtp->t_value);
*tpp = ltp;
return(1);
}
if( rtp->t_op == CLONG ) {
anylong++;
rval = rtp->t_lvalue;
}
else if( rtp = constant(rtp) )
rval = rtp->t_value;
else
return(0);
}
i = lval;
j = rval;
switch( op ) {
case ADD:
lval =+ rval;
break;
case SUB:
lval =- rval;
break;
case MULT:
case DIV:
case MOD:
case LSH:
case RSH:
case XOR:
if( anylong )
return(0);
switch( op ) {
case MULT:
lval = i * j;
break;
case DIV:
lval = i / j;
break;
case MOD:
lval = i % j;
break;
case RSH:
lval = i >> j;
break;
case LSH:
lval = i << j;
break;
case XOR:
lval = i ^ j;
break;
}
break;
case GREAT:
lval = (lval>rval);
break;
case GREATEQ:
lval = (lval>=rval);
break;
case LESS:
lval = (lval<rval);
break;
case LESSEQ:
lval = (lval<=rval);
break;
case UMINUS:
lval = -lval;
break;
case COMPL:
lval = ~lval;
break;
case NOT:
lval = !lval;
break;
case OR:
lval =| rval;
break;
case AND:
lval =& rval;
break;
default:
return(0);
}
if( anylong )
ltp = lcnalloc(LONG,lval);
else
ltp->t_value = lval;
*tpp = ltp;
return(1);
}
/* power2 - do multiply and divide by powers of two*/
/* This changes multiplies and divides by constant powers of two*/
/* to shifts.*/
power2(tpp) /* returns 0 if not power of two*/
struct tnode **tpp; /* pointer to expression tree*/
{
register char *p;
register int i, j, op;
register struct tnode *tp;
tp = *tpp;
if( p = constant(tp->t_right) ) {
if( (i=onebit(p->t_value)) < 0 )
return(0);
switch( op = tp->t_op ) {
case MULT:
case LMULT:
op = LSH;
break;
case EQMULT:
case LEQMULT:
op = EQLSH;
break;
case DIV:
case LDIV:
op = RSH;
break;
case EQDIV:
case LEQDIV:
op = EQRSH;
break;
case MOD:
case LMOD:
op = AND;
i = p->t_value - 1;
break;
case EQMOD:
case LEQMOD:
op = EQAND;
i = p->t_value - 1;
break;
default:
return(0);
}
tp->t_op = op;
p->t_value = i;
return(1);
}
return(0);
}
/* chklong - check for tree being a long*/
chklong(tp) /* returns 1 if long, 0 otherwise*/
struct tnode *tp; /* pointer to expression tree*/
{
if( tp->t_op == INT2L && unsign(tp->t_left->t_type) == 0 )
return(0);
if( tp->t_op == CLONG )
return(1);
return( longorptr(tp->t_type) );
}
/* multop - handle multiplicative operators*/
/* This checks for powers of two optimizations, then for a hard*/
/* long operation.*/
multop(tpp) /* returns ptr to expression tree*/
struct tnode **tpp; /* pointer to expression tree*/
{
register struct tnode *ltp, *tp, *rtp, *p;
register int change;
register long l;
tp = *tpp;
if( change = power2(tpp) )
tp = *tpp;
if( chklong(rtp=tp->t_right) || chklong(ltp=tp->t_left) ) {
switch( tp->t_op ) {
case MULT:
tp->t_op = LMULT; /*hard if either is long*/
break;
case DIV:
case MOD:
if( chklong(rtp) ) { /*only hard if divisor is long*/
tp->t_op =+ (LMULT-MULT);
if( rtp->t_op == CLONG )
rtp->t_op = DCLONG;
}
break;
case EQDIV:
case EQMOD:
if( chklong(rtp) == 0 )
break;
if( rtp->t_op == CLONG )
rtp->t_op = DCLONG;
case EQMULT:
if( ltp->t_op == SYMBOL && ltp->t_sc == REGISTER )
error("hard long to register");
else {
tp->t_op =+ (LEQMULT-EQMULT);
tp->t_left = tnalloc(ADDR,LONG|POINTER,0,0,ltp,null);
change++;
}
break;
}
}
return(change);
}
/* onebit - returns whether constant is power of two (one bit on)*/
onebit(val) /* returns bit number or -1*/
int val; /* constant value to check*/
{
register int i;
for( i = 15; val != 0; val =<< 1, i-- )
if( val & 0100000 )
break;
if( val != 0100000 )
return(-1);
return(i);
}

View File

@@ -0,0 +1,162 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "icode.h"
#define NODEBUG 1
char brtab[][2];
int invrel[];
int swaprel[];
char *strtab[];
char null[];
/*operator tree node for unary and binary operators*/
struct tnode {
int t_op; /*operator*/
int t_type; /*data type of result*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_value; /*value or label number*/
};
struct lconode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
int t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
char t_symbol[SSIZE]; /*symbol name*/
};
/*68000 special - indexed symbol node*/
/*this is used to generate a An(off,Xn.type) address*/
struct indexnode {
int t_op;
int t_type;
int t_su;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_xreg;
int t_xtype;
};
int lflag;
int dflag;
int mflag;
int cflag;
int eflag;
int fflag;
int oflag;
struct io_buf ibuf, obuf;
int lineno;
int naregs;
int ndregs;
int errcnt;
int opinfo[];
int nextlabel;
char null[];
char optab[][6];
char *mnemonics[];
char *codeskels[];
int stacksize;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *canon();
char *commute();
char *constant();
char *match();
char *addptree();
char *fixbfield();
char *coffset();
char *tcopy();
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define commop(op) ((opinfo[op]&OPCOM)!=0)
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define QUICKVAL 8
#define LEP 14
#define FORCC 1
#define FOREFF 2
#define FORSTACK 3
#define FORCREG 4
#define FORSP 5
#define FORREG 4
#define HICREG 2
#define NCREGS 3
#define AREGLO 8
#define IMMED 1
#define NOTIMMED 0
#define LOFFSET 2
#define NOTLOFFSET 0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*built-in literals*/
#define MOV 128
#define MOVL 129
#define JSR 130
#define CLR 131
#define CLRL 132
#define EXTW 133
#define EXTL 134
#define LEA 135
#define STK 136
/*built-in macros*/
#define TREE 141
#define LEFT 142
#define RIGHT 143
#define LOFFSET 144
#define ROFFSET 145
#define LADDR 146
#define RADDR 147
#define CR 148
#define NR 149
#define CAR 150
#define NAR 151
#define TLEFT 152
#define TRIGHT 153
#define TEITHER 154
#define TLEFTL 155
#define OP 156
#define AOP 157
#define MODSWAP 158
#define EXL 159
#define EXLR 160
#define EXLRN 161
#define EXRL 162
#define EXRLN 163
#define PSH 164
#define POP 165
#define POP8 166
/*modifiers for compiling sub-trees*/
#define S_INDR 1 /*indirection*/
#define S_STACK 2 /*onto stack*/
#define S_FORCC 4 /*set condition codes*/
#define S_NEXT 8 /*into next register*/
/*Sethy-Ullman values*/
#define SU_ZERO 0x000 /*zero*/
#define SU_ONE 0x100 /*one*/
#define SU_SMALL 0x200 /*constant between 1 and 8*/
#define SU_QUICK 0x300 /*quick constant between -128 and 127*/
#define SU_CONST 0x400 /*any constant*/
#define SU_AREG 0x500 /*A register*/
#define SU_REG 0x600 /*register*/
#define SU_ADDR 0x700 /*addressable*/
#define SU_XREG 0x800 /*A register used as data...*/
#define SU_EASY 0x900 /*easy*/
#define SU_HARD 0xa00 /*hard*/
#define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
#define SU_ANY 0xf00 /*anything*/
#define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
#define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
#define LOADABLE(x) (x->t_su<=SU_XREG)
/*flag byte (operand type):*/
#define T_CHAR 1 /*char only*/
#define T_SHORT 2 /*short*/
#define T_INT 3 /*int only*/
#define T_LONG 4 /*long*/
#define T_UCHAR 5 /*unsigned char*/
#define T_USHORT 6 /*unsigned short*/
#define T_UNSN 7 /*unsigned int*/
#define T_ULONG 8 /*unsigned long*/
#define T_FLOAT 9 /*float*/
#define T_DOUB 10 /*double*/
#define T_ANY 11 /*int or word (implied)*/
#define T_INDR 0x10 /*pointer type (bit)*/
struct skeleton {
int sk_left;
int sk_right;
char *sk_def;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
$ diff CANON.C drb1:[cpm68k.release.cgen]CANON.C
$ diff CODEGEN.C drb1:[cpm68k.release.cgen]CODEGEN.C
$ diff CSKELS.C drb1:[cpm68k.release.cgen]CSKELS.C
$ diff INIT.C drb1:[cpm68k.release.cgen]INIT.C
$ diff INITX.C drb1:[cpm68k.release.cgen]INITX.C
$ diff INTERF.C drb1:[cpm68k.release.cgen]INTERF.C
$ diff MAIN.C drb1:[cpm68k.release.cgen]MAIN.C
$ diff OPTAB.C drb1:[cpm68k.release.cgen]OPTAB.C
$ diff PUTEXPR.C drb1:[cpm68k.release.cgen]PUTEXPR.C
$ diff SUCOMP.C drb1:[cpm68k.release.cgen]SUCOMP.C
$ diff TABL.C drb1:[cpm68k.release.cgen]TABL.C
$ diff UTIL.C drb1:[cpm68k.release.cgen]UTIL.C
$ diff CGEN.H drb1:[cpm68k.release.cgen]CGEN.H
$ diff CSKEL.H drb1:[cpm68k.release.cgen]CSKEL.H
$ diff ICODE.H drb1:[cpm68k.release.cgen]ICODE.H

View File

@@ -0,0 +1,215 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*intermediate code operators*/
/*0=>EOF, special operator*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define LCGENOP 47 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/* data registers*/
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8
#define TRUE 1
#define FALSE 0
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /*terminal nodes*/
#define RPNPRI 1 /*) and ]*/
#define CALPRI 2 /*in-stack call, ( or [*/
#define COLPRI 3 /*init or case priority for : or ,*/
#define STKPRI 4 /*priority of end of stack*/
#define COMPRI 5 /*normal priority for ,*/
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
#define QMKPRI 7 /*?:*/
#define LORPRI 8 /*||*/
#define LNDPRI 9 /*&&*/
#define ORPRI 10 /*|, !*/
#define ANDPRI 11 /*&*/
#define EQLPRI 12 /*==, !=*/
#define RELPRI 13 /*>, <, >=, <=*/
#define SHFPRI 14 /*<<, >>*/
#define ADDPRI 15 /*+, -*/
#define MULPRI 16 /**, /, %*/
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
#define LPNPRI 18 /*., ->, [, (, function call*/
#define PSTPRI 19 /*in-stack post--, post++*/
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE];

View File

@@ -0,0 +1,381 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*intermediate code operators*/
/*0=>EOF, special operator*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define LCGENOP 47 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/* data registers*/
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8
#define TRUE 1
#define FALSE 0
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /*terminal nodes*/
#define RPNPRI 1 /*) and ]*/
#define CALPRI 2 /*in-stack call, ( or [*/
#define COLPRI 3 /*init or case priority for : or ,*/
#define STKPRI 4 /*priority of end of stack*/
#define COMPRI 5 /*normal priority for ,*/
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
#define QMKPRI 7 /*?:*/
#define LORPRI 8 /*||*/
#define LNDPRI 9 /*&&*/
#define ORPRI 10 /*|, !*/
#define ANDPRI 11 /*&*/
#define EQLPRI 12 /*==, !=*/
#define RELPRI 13 /*>, <, >=, <=*/
#define SHFPRI 14 /*<<, >>*/
#define ADDPRI 15 /*+, -*/
#define MULPRI 16 /**, /, %*/
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
#define LPNPRI 18 /*., ->, [, (, function call*/
#define PSTPRI 19 /*in-stack post--, post++*/
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE] = {0};
#define NODEBUG 1
char brtab[][2];
int invrel[];
int swaprel[];
char *strtab[];
char null[]={0};
/*operator tree node for unary and binary operators*/
struct tnode {
int t_op; /*operator*/
int t_type; /*data type of result*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_value; /*value or label number*/
};
struct lconode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
int t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
char t_symbol[SSIZE]; /*symbol name*/
};
/*68000 special - indexed symbol node*/
/*this is used to generate a An(off,Xn.type) address*/
struct indexnode {
int t_op;
int t_type;
int t_su;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_xreg;
int t_xtype;
};
int lflag=0;
int dflag=0;
int mflag=0;
int cflag=0;
int eflag=0;
int fflag=0;
int oflag=0;
struct io_buf ibuf = {0},
obuf = {0};
int lineno=0;
int naregs=0;
int ndregs=0;
int errcnt=0;
int opinfo[];
int nextlabel;
char null[];
char optab[][6];
char *mnemonics[];
char *codeskels[];
int stacksize;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *canon();
char *commute();
char *constant();
char *match();
char *addptree();
char *fixbfield();
char *coffset();
char *tcopy();
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define commop(op) ((opinfo[op]&OPCOM)!=0)
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define QUICKVAL 8
#define LEP 14
#define FORCC 1
#define FOREFF 2
#define FORSTACK 3
#define FORCREG 4
#define FORSP 5
#define FORREG 4
#define HICREG 2
#define NCREGS 3
#define AREGLO 8
#define IMMED 1
#define NOTIMMED 0
#define LOFFSET 2
#define NOTLOFFSET 0
int bol=0;
int errflg=0;
int onepass=0;
char *opap=0;
int stacksize=0;
fflush(fp)
char *fp;
{
return(myfflush(fp));
}

View File

@@ -0,0 +1,381 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*intermediate code operators*/
/*0=>EOF, special operator*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define LCGENOP 47 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/* data registers*/
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8
#define TRUE 1
#define FALSE 0
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /*terminal nodes*/
#define RPNPRI 1 /*) and ]*/
#define CALPRI 2 /*in-stack call, ( or [*/
#define COLPRI 3 /*init or case priority for : or ,*/
#define STKPRI 4 /*priority of end of stack*/
#define COMPRI 5 /*normal priority for ,*/
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
#define QMKPRI 7 /*?:*/
#define LORPRI 8 /*||*/
#define LNDPRI 9 /*&&*/
#define ORPRI 10 /*|, !*/
#define ANDPRI 11 /*&*/
#define EQLPRI 12 /*==, !=*/
#define RELPRI 13 /*>, <, >=, <=*/
#define SHFPRI 14 /*<<, >>*/
#define ADDPRI 15 /*+, -*/
#define MULPRI 16 /**, /, %*/
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
#define LPNPRI 18 /*., ->, [, (, function call*/
#define PSTPRI 19 /*in-stack post--, post++*/
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE] = {0};
#define NODEBUG 1
char brtab[][2];
int invrel[];
int swaprel[];
char *strtab[];
char null[]={0};
/*operator tree node for unary and binary operators*/
struct tnode {
int t_op; /*operator*/
int t_type; /*data type of result*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
struct tnode *t_left; /*left sub-tree*/
struct tnode *t_right; /*right sub-tree (undefined if unary)*/
};
/*constant terminal node*/
struct conode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_value; /*value or label number*/
};
struct lconode {
int t_op; /*operator*/
int t_type; /*type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
long t_lvalue; /*value or label number*/
};
/*local symbol terminal node*/
struct symnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
int t_label; /*label number if static*/
};
/*external symbol reference node*/
struct extnode {
int t_op; /*operator*/
int t_type; /*symbol data type*/
int t_su; /*Sethy-Ullman number*/
int t_ssp;
int t_sc; /*storage class*/
int t_offset; /*register offset*/
int t_reg; /*register number*/
char t_symbol[SSIZE]; /*symbol name*/
};
/*68000 special - indexed symbol node*/
/*this is used to generate a An(off,Xn.type) address*/
struct indexnode {
int t_op;
int t_type;
int t_su;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_xreg;
int t_xtype;
};
int lflag=0;
int dflag=0;
int mflag=0;
int cflag=0;
int eflag=0;
int fflag=0;
int oflag=0;
struct io_buf ibuf = {0},
obuf = {0};
int lineno=0;
int naregs=0;
int ndregs=0;
int errcnt=0;
int opinfo[];
int nextlabel;
char null[];
char optab[][6];
char *mnemonics[];
char *codeskels[];
int stacksize;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *canon();
char *commute();
char *constant();
char *match();
char *addptree();
char *fixbfield();
char *coffset();
char *tcopy();
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
#define leafop(op) ((opinfo[op]&OPTERM)!=0)
#define notleafop(op) ((opinfo[op]&OPTERM)==0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define commop(op) ((opinfo[op]&OPCOM)!=0)
#define convop(op) ((opinfo[op]&OPCONVS)!=0)
#define notconvop(op) ((opinfo[op]&OPCONVS)==0)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define QUICKVAL 8
#define LEP 14
#define FORCC 1
#define FOREFF 2
#define FORSTACK 3
#define FORCREG 4
#define FORSP 5
#define FORREG 4
#define HICREG 2
#define NCREGS 3
#define AREGLO 8
#define IMMED 1
#define NOTIMMED 0
#define LOFFSET 2
#define NOTLOFFSET 0
int bol=0;
int errflg=0;
int onepass=0;
char *opap=0;
int stacksize=0;
fflush(fp)
char *fp;
{
return(myfflush(fp));
}

View File

@@ -0,0 +1,6 @@
fflush(fp)
char *fp;
{
return(myfflush(fp));
}
char *null = "";

View File

@@ -0,0 +1,137 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
int bol;
int onepass;
/* outexpr - output expression*/
outexpr(tp) /* returns - none*/
struct tnode *tp; /* pointer to tree node*/
{
if( dflag )
outline();
if( exprok(tp) )
scodegen(canon(tp),FOREFF,0);
}
outforreg(tp)
struct tnode *tp;
{
register int reg;
if( dflag )
outline();
if( exprok(tp) && (reg=scodegen(canon(tp),FORREG,0)) != 0 )
outmovr(reg,0,tp);
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
if( dflag )
outline();
if( exprok(tp) )
condbr(canon(tp),dir,lab,0);
}
outinit(tp) /* returns - none*/
struct tnode *tp;
{
register int typeout;
if( dflag )
outline();
if( exprok(tp) ) {
typeout = tp->t_type;
tp = canon(tp);
if( tp->t_op == ADDR )
tp = tp->t_left;
if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
if( tp->t_op == SYMBOL )
printf(".dc.l ");
else {
printf(".dc.");
outtype(typeout);
putchar(' ');
}
outaexpr(tp,IMMED);
}
else
error("invalid initialization");
putchar('\n');
}
}
/* snalloc - code generator symbol node allocation*/
/* This might be coalesced into parser snalloc.*/
char *snalloc(type,sc,offset,dp,ssp) /* returns ptr to node alloced*/
int type; /* type of symbol*/
int sc; /* storage class*/
int offset; /* offset from Local Environment Ptr*/
int dp; /*for compatability with parser*/
int ssp; /*for compatability with parser*/
{
register struct symnode *sp;
sp = talloc(sizeof(*sp));
sp->t_op = SYMBOL;
sp->t_type = type;
sp->t_su = dp;
sp->t_ssp = ssp;
sp->t_sc = sc;
switch( sc ) {
case STATIC:
sp->t_offset = 0;
sp->t_reg = 0;
sp->t_label = offset;
break;
case REGISTER:
sp->t_offset = 0;
sp->t_reg = offset;
sp->t_label = 0;
break;
case AUTO:
sp->t_sc = REGOFF;
sp->t_offset = offset;
sp->t_reg = LEP;
sp->t_label = 0;
break;
default:
sp->t_offset = offset;
sp->t_reg = 0;
sp->t_label = 0;
break;
}
return(sp);
}
exprok(tp)
struct tnode *tp;
{
if( tp < exprarea || tp > &exprarea[EXPSIZE] )
return(0);
if( leafop(tp->t_op) )
return(1);
if( binop(tp->t_op) && exprok(tp->t_right) == 0 )
return(0);
return( exprok(tp->t_left) );
}
outline()
{
if( onepass && bol == 0 )
putchar('\n');
printf("*line %d\n",lineno);
}

View File

@@ -0,0 +1,2 @@
lo68 -r -s s.o canon.o codegen.o cskels.o interf.o main.o optab.o putexpr.o sucomp.o tabl.o util.o initx.o lib6.a
ren c168.rel=c.out

View File

@@ -0,0 +1,45 @@
$ num
CANON.C
CANON.lis
$ num
CODEGEN.C
CODEGEN.lis
$ num
CSKELS.C
CSKELS.lis
$ num
INIT.C
INIT.lis
$ num
INITX.C
INITX.lis
$ num
INTERF.C
INTERF.lis
$ num
MAIN.C
MAIN.lis
$ num
OPTAB.C
OPTAB.lis
$ num
PUTEXPR.C
PUTEXPR.lis
$ num
SUCOMP.C
SUCOMP.lis
$ num
TABL.C
TABL.lis
$ num
UTIL.C
UTIL.lis
$ num
CGEN.H
CGEN.lst
$ num
CSKEL.H
CSKEL.lst
$ num
ICODE.H
ICODE.lst

View File

@@ -0,0 +1,392 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
char *opap;
int errflg;
int nextlabel 10000;
char *readtree();
char *readsym();
/* main - main routine, handles arguments and files*/
main(argc,argv) /* returns - none*/
int argc; /* arg count*/
char **argv; /* arg pointers*/
{
register char *q;
register int i;
for( i = 3; i < argc; i++ ) {
q = argv[i];
if( *q++ != '-' )
usage();
while( 1 ) {
switch( *q++ ) {
case 'D':
case 'd':
dflag++;
continue;
case 'L':
case 'l':
lflag++;
continue;
case 'e':
case 'E':
eflag++;
continue;
case 'f':
case 'F':
fflag++;
continue;
case 'm':
case 'M':
mflag++;
continue;
case 'o':
case 'O':
oflag++;
continue;
case 'c':
case 'C':
cflag++;
continue;
case '\0':
break;
default:
usage();
}
break;
}
}
if( argc < 3 )
usage();
if( fopen(argv[1],&ibuf,0) < 0 )
ferror("can't open %s\n",argv[1]);
if( fcreat(argv[2],&obuf,0) < 0 )
ferror("can't create %s\n",argv[2]);
readicode();
fflush(&obuf);
exit(errcnt!=0);
}
/* readicode - read intermediate code and dispatch output*/
/* This copies assembler lines beginning with '(' to assembler*/
/* output and builds trees starting with '.' line.*/
readicode() /*returns - none*/
{
register int c;
register struct tnode *tp;
while( (c=getc(&ibuf)) > 0 ) {
switch(c) {
case '.':
lineno = readint();
opap = exprarea;
if( tp = readtree() ) {
#ifndef NODEBUG
if( cflag )
putexpr("readicode",tp);
#endif
switch( tp->t_op ) {
case INIT:
outinit(tp->t_left);
break;
case IFGOTO:
outifgoto(tp->t_left,tp->t_type,tp->t_su);
break;
case CFORREG:
outforreg(tp->t_left);
break;
default:
outexpr(tp);
break;
}
}
break;
case '(':
while( (c=getc(&ibuf)) != '\n' )
putchar(c);
putchar(c);
break;
default:
error("intermediate code error");
break;
}
}
}
/* readtree - recursive intermediate code tree read*/
char *readtree() /* returns ptr to expression tree*/
{
register int op, type, sc;
register struct tnode *tp, *rtp;
char sym[SSIZE];
long l;
if( (op=readint()) <= 0 )
return(0);
type = readint();
switch( op ) {
case SYMBOL:
if( (sc=readint()) == EXTERNAL )
tp = cenalloc(type,sc,readsym(sym));
else
tp = snalloc(type,sc,readint(),0,0);
break;
case CINT:
tp = cnalloc(type,readint());
break;
case CLONG:
l.hiword = readint();
l.loword = readint();
tp = lcnalloc(type,l);
break;
case IFGOTO:
case BFIELD:
sc = readint();
if( tp = readtree() )
tp = tnalloc(op,type,sc,0,tp,null);
break;
default:
if( binop(op) ) {
if( (tp=readtree()) == 0 )
return(0);
if( (rtp=readtree()) == 0 )
return(0);
tp = tnalloc(op,type,0,0,tp,rtp);
}
else if( tp = readtree() )
tp = tnalloc(op,type,0,0,tp,null);
break;
}
return(tp);
}
/* readint - reads an integer value from intermediate code*/
readint()
{
register int i, c;
i = 0;
while(1) {
switch( c = getc(&ibuf) ) {
case '.':
case '\n':
return(i);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i =<< 4;
i =+ (c-'0');
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
i =<< 4;
i =+ (c-('A'-10));
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
i =<< 4;
i =+ (c-('a'-10));
break;
default:
error("intermediate code error");
}
}
}
/* readsym - read a symbol from intermediate code*/
char *readsym(sym)
char *sym;
{
register int i, c;
register char *s;
for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; )
if( --i >= 0 )
*s++ = c;
if( i > 0 )
*s = '\0';
return(sym);
}
/* error - output an error message*/
error(s,x1,x2,x3,x4,x5,x6)
char *s;
int x1, x2, x3, x4, x5, x6;
{
errcnt++;
errflg++;
if( lineno != 0 )
printf("** %d: ",lineno);
printf(s,x1,x2,x3,x4,x5,x6);
putchar('\n');
errflg--;
}
/* ferror - output error message and die*/
ferror(s,x1,x2,x3,x4,x5,x6)
char *s;
int x1, x2, x3, x4, x5, x6;
{
error(s,x1,x2,x3,x4,x5,x6);
exit(1);
}
/* tnalloc - allocate binary expression tree node*/
char *tnalloc(op,type,info,dummy,left,right) /* returns ptr to node made*/
int op; /* operator*/
int type; /* resultant node type*/
int info; /* info field*/
int dummy; /* dummy field - used to match pass1 args*/
struct tnode *left; /* left sub-tree*/
struct tnode *right; /* righst sub-tree*/
{
register struct tnode *tp;
tp = talloc(sizeof(*tp));
tp->t_op = op;
tp->t_type = type;
tp->t_su = info; /* info for bit-field & condbr's*/
tp->t_left = left;
tp->t_right = right;
return(tp);
}
/* cnalloc - allocate constant expression tree node*/
char *cnalloc(type,value) /* returns pointer to node alloced*/
int type; /* type of constant*/
int value; /* value of constant*/
{
register struct conode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CINT;
cp->t_type = type;
cp->t_value = value;
return(cp);
}
/* lcnalloc - allocate constant expression tree node*/
char *lcnalloc(type,value) /* returns pointer to node alloced*/
int type; /* type of constant*/
long value; /* value of constant*/
{
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CLONG;
cp->t_type = type;
cp->t_lvalue = value;
return(cp);
}
/* talloc - allocate expression tree area*/
char *talloc(size) /* returns pointer to area alloced*/
int size; /* number of bytes to alloc*/
{
register char *p;
p = opap;
if( p + size >= &exprarea[EXPSIZE] )
ferror("expression too complex");
opap = p + size;
return(p);
}
/* symcopy - copy symbol*/
symcopy(sym1,sym2) /* returns - none*/
char *sym1; /* from symbol*/
char *sym2; /* to symbol*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
*q++ = (*p ? *p++ : '\0');
}
/* usage - ouput usage message*/
usage()
{
ferror("usage: c168 icode asm [-DLmec]");
}
/* outgoto - output "bra L[labno]"*/
outgoto(lab)
int lab;
{
if( lab > 0 )
printf("bra L%d\n",lab);
}
/* outlab - output "L[labno]:"*/
outlab(lab)
int lab;
{
if( lab > 0 )
printf("L%d:",lab);
}
/* putchar - special version*/
/* This allows the use of printf for error messages, debugging*/
/* output and normal output.*/
putchar(c) /* returns - none*/
char c; /* character to output*/
{
if( errflg ) /*error message?*/
write(1,&c,1); /*write to standard output*/
else {
if( dflag > 1 )
write(1,&c,1); /*to standard output*/
putc(c,&obuf); /*put to assembler file*/
}
}

View File

@@ -0,0 +1,14 @@
$ set def [steve.cpm68k.c.cgen]
$ !
$ cc68 CANON
$ cc68 CODEGEN
$ cc68 CSKELS
$ cc68 INTERF
$ cc68 MAIN
$ cc68 OPTAB
$ cc68 PUTEXPR
$ cc68 SUCOMP
$ cc68 TABL
$ cc68 UTIL
$ cc68 initx
$ @relink

View File

@@ -0,0 +1,100 @@
cp68 CANON.c x.i
c068 x.i x.ic x.st
c168 x.ic CANON.s -l
as68 -l -u CANON.s
era x.i
era x.ic
era x.st
era CANON.s
cp68 CODEGEN.c x.i
c068 x.i x.ic x.st
c168 x.ic CODEGEN.s -l
as68 -l -u CODEGEN.s
era x.i
era x.ic
era x.st
era CODEGEN.s
cp68 CSKELS.c x.i
c068 x.i x.ic x.st
c168 x.ic CSKELS.s -l
as68 -l -u CSKELS.s
era x.i
era x.ic
era x.st
era CSKELS.s
cp68 INTERF.c x.i
c068 x.i x.ic x.st
c168 x.ic INTERF.s -l
as68 -l -u INTERF.s
era x.i
era x.ic
era x.st
era INTERF.s
cp68 MAIN.c x.i
c068 x.i x.ic x.st
c168 x.ic MAIN.s -l
as68 -l -u MAIN.s
era x.i
era x.ic
era x.st
era MAIN.s
cp68 OPTAB.c x.i
c068 x.i x.ic x.st
c168 x.ic OPTAB.s -l
as68 -l -u OPTAB.s
era x.i
era x.ic
era x.st
era OPTAB.s
cp68 PUTEXPR.c x.i
c068 x.i x.ic x.st
c168 x.ic PUTEXPR.s -l
as68 -l -u PUTEXPR.s
era x.i
era x.ic
era x.st
era PUTEXPR.s
cp68 SUCOMP.c x.i
c068 x.i x.ic x.st
c168 x.ic SUCOMP.s -l
as68 -l -u SUCOMP.s
era x.i
era x.ic
era x.st
era SUCOMP.s
cp68 TABL.c x.i
c068 x.i x.ic x.st
c168 x.ic TABL.s -l
as68 -l -u TABL.s
era x.i
era x.ic
era x.st
era TABL.s
cp68 UTIL.c x.i
c068 x.i x.ic x.st
c168 x.ic UTIL.s -l
as68 -l -u UTIL.s
era x.i
era x.ic
era x.st
era UTIL.s
cp68 initx.c x.i
c068 x.i x.ic x.st
c168 x.ic initx.s -l
as68 -l -u initx.s
era x.i
era x.ic
era x.st
era initx.s
submit link

View File

@@ -0,0 +1,259 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#define I_NULL 0
#define I_ADD 1
#define I_INC 2
#define I_SUB 3
#define I_DEC 4
#define I_MULS 5
#define I_MULU 6
#define I_DIVS 7
#define I_DIVU 8
#define I_ASR 9
#define I_LSR 10
#define I_ASL 11
#define I_LSL 12
#define I_AND 13
#define I_OR 14
#define I_EOR 15
#define I_NEG 16
#define I_NOT 17
#define I_MOVE 18
#define I_CLR 19
#define I_CMP 20
#define I_TST 21
#define I_LMUL 22
#define I_LDIV 23
#define I_LREM 24
#define I_LEML 25
#define I_LEDV 26
#define I_LERM 27
#define I_BEQ 28
#define I_BNE 29
#define I_BGT 30
#define I_BGE 31
#define I_BLT 32
#define I_BLE 33
#define I_BLS 34
#define I_BLO 35
#define I_BCC 36
#define I_BHI 37
#define I_BRA 38
#define I_NOP 39
#define I_BTST 40
char *mnemonics[] {
"",
"add",
"inc",
"sub",
"dec",
"muls",
"mulu",
"divs",
"divu",
"asr",
"lsr",
"asl",
"lsl",
"and",
"or",
"eor",
"neg",
"not",
"move",
"clr",
"cmp",
"tst",
"lmul",
"_ldiv",
"lrem",
"almul",
"aldiv",
"alrem",
"beq",
"bne",
"bgt",
"bge",
"blt",
"ble",
"bls",
"blo",
"bcc",
"bhi",
"jmp",
"*nop",
"btst",
};
#define FE_EQOP 1
#define FE_ASSIGN 2
#define FE_EQSHFT 3
#define FE_EQXOR 4
#define FE_EQADDR 5
#define FC_FIX 6
#define FC_REL 7
#define FC_BTST 8
#define FS_OP 9
#define FS_ITL 10
#define FS_LD 11
#define FR_ADD 12
#define FR_MULT 13
#define FR_DIV 14
#define FR_SHFT 15
#define FR_XOR 16
#define FR_NEG 17
#define FR_EQOP 18
#define FR_POSTOP 19
#define FR_ASSIGN 20
#define FR_EQMULT 21
#define FR_EQDIV 22
#define FR_EQSHFT 23
#define FR_EQXOR 24
#define FR_CALL 25
#define FR_ITL 26
#define FR_LTI 27
#define FR_LD 28
#define FR_LEMUL 29
#define FR_EQADDR 30
/*
* You left these out, Bill.
*/
char fe_eqop[], fe_assign[], fe_eqshft[], fe_eqxor[], fe_eqaddr[];
char fc_fix[], fc_rel[], fc_btst[];
char fs_op[], fs_itl[], fs_ld[];
char fr_op[], fr_mult[], fr_div[], fr_shft[], fr_xor[], fr_neg[],
fr_eqop[], fr_postop[], fr_assign[], fr_eqmult[], fr_eqdiv[],
fr_eqshft[], fr_eqxor[], fr_call[], fr_itl[], fr_lti[],
fr_ld[], fr_lemul[], fr_eqaddr[];
char *codeskels[] {
0,
fe_eqop,
fe_assign,
fe_eqshft,
fe_eqxor,
fe_eqaddr,
fc_fix,
fc_rel,
fc_btst,
fs_op,
fs_itl,
fs_ld,
fr_op,
fr_mult,
fr_div,
fr_shft,
fr_xor,
fr_neg,
fr_eqop,
fr_postop,
fr_assign,
fr_eqmult,
fr_eqdiv,
fr_eqshft,
fr_eqxor,
fr_call,
fr_itl,
fr_lti,
fr_ld,
fr_lemul,
fr_eqaddr,
};
/*This is the major table directing the code generation process.*/
/*It is indexed by an O_op operator, which is obtained from the*/
/*opinfo table for an intermediate code operator. The actual*/
/*code skeleton macros are in cskels.c, which are in a linked*/
/*list in order of decreasing order of difficulty.*/
char optab[][6] {
/* I I2 effect cc's stack register*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*NULL*/
I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*ADD*/
I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*SUB*/
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*MULT*/
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*DIV*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*MOD*/
I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*RSH*/
I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*LSH*/
I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*AND*/
I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*OR*/
I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*XOR*/
I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*NOT*/
I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*NEG*/
I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*COMPL*/
I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*PREDEC*/
I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*PREINC*/
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*POSTDEC*/
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*POSTINC*/
I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*ASSIGN*/
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQADD*/
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQSUB*/
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_EQMULT, /*EQMULT*/
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_EQDIV, /*EQDIV*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_EQDIV, /*EQMOD*/
I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*EQRSH*/
I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*EQLSH*/
I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQAND*/
I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*EQOR*/
I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*EQXOR*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*FJSR*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*EQUALS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*NEQUALS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*GREAT*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*GREATEQ*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*LESS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*LESSEQ*/
I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*INT2L*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*LONG2I*/
I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*BTST*/
I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*LOAD*/
I_MULS, I_LMUL, I_NULL, I_NULL, I_NULL, FR_MULT, /*LMULT*/
I_DIVS, I_LDIV, I_NULL, I_NULL, I_NULL, FR_DIV, /*LDIV*/
I_DIVS, I_LREM, I_NULL, I_NULL, I_NULL, FR_DIV, /*LMOD*/
I_LEML, I_LEML, I_NULL, I_NULL, I_NULL, FR_LEMUL, /*LEQMULT*/
I_LEDV, I_LEDV, I_NULL, I_NULL, I_NULL, FR_LEMUL, /*LEQDIV*/
I_LERM, I_LERM, I_NULL, I_NULL, I_NULL, FR_LEMUL, /*LEQMOD*/
I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*EQADDR*/
};
/*this maps comparison operators and comparison types into the*/
/*actual branch opcode used.*/
char brtab[][2] {
I_BEQ, I_BEQ, /*EQUALS*/
I_BNE, I_BNE, /*NEQUALS*/
I_BGT, I_BHI, /*GREAT*/
I_BGE, I_BCC, /*GREATEQ*/
I_BLT, I_BLO, /*LESS*/
I_BLE, I_BLS, /*LESSEQ*/
};
/*turns !x>y into x<=y*/
int invrel[] { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
/*turns x>y into y<=x*/
int swaprel[] { EQUALS, NEQUALS, LESS, LESSEQ, GREAT, GREATEQ };
/*code skeleton built-in strings*/
char *strtab[] {
"move", /*MOV*/
"move.l", /*MOVL*/
"jsr", /*JSR*/
"clr", /*CLR*/
"clr.l", /*CLRL*/
"ext.w", /*EXTW*/
"ext.l", /*EXTL*/
"lea", /*LEA*/
"(sp)", /*STK*/
};

View File

@@ -0,0 +1,29 @@
/*****************************************************************************
*
* P R I N T F F U N C T I O N
* -------------------------------
*
* The "printf" function is used to write data to the standard output.
*
* calling sequence:
*
* printf(format,arg1,arg2, ... argn);
*
* Where:
*
* format is a text string as described in K & R
* Arg1-argn are optional arguments to be converted and
* placed in the output
*
*****************************************************************************/
__putc(fd,c) /* WSL is backwards!! */
{ /****************************/
putchar(c); /* Output character */
} /****************************/
printf (fmt,a1) /* Declare args */
char *fmt; /* -> Format string */
int a1; /* Whatever the right size */
{ /****************************/
_printf (0,__putc,fmt,&a1); /* Invoke secret routine */
} /****************************/

View File

@@ -0,0 +1,252 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#ifndef NODEBUG
char invalid[] "INVALID";
char *opname[] {
invalid, /*0*/
"+", /*1*/
"-", /*2*/
"*", /*3*/
"/", /*4*/
"%", /*5*/
">>", /*6*/
"<<", /*7*/
"&", /*8*/
"|", /*9*/
"^", /*10*/
"!", /*11*/
"U-", /*12*/
"~", /*13*/
"--p", /*14*/
"++p", /*15*/
"p--", /*16*/
"p++", /*17*/
"=", /*18*/
"+=", /*19*/
"-=", /*20*/
"*=", /*21*/
"/=", /*22*/
"%=", /*23*/
">>=", /*24*/
"<<=", /*25*/
"&=", /*26*/
"|=", /*27*/
"^=", /*28*/
"jsr", /*29*/
"==", /*30*/
"!=", /*31*/
">", /*32*/
">=", /*33*/
"<", /*34*/
"<=", /*35*/
"int->long", /*36*/
"long->int", /*37*/
"btst", /*38*/
"load", /*39*/
"long*", /*40*/
"long/", /*41*/
"long%", /*42*/
"long*=", /*43*/
"long/=", /*44*/
"long%=", /*45*/
"=addr", /*46*/
invalid, /*47*/
invalid, /*48*/
invalid, /*49*/
invalid, /*50*/
invalid, /*51*/
invalid, /*52*/
invalid, /*53*/
invalid, /*54*/
invalid, /*55*/
invalid, /*56*/
invalid, /*57*/
invalid, /*58*/
invalid, /*59*/
"U&", /*60*/
"U*", /*61*/
"&&", /*62*/
"||", /*63*/
"?", /*64*/
":", /*65*/
",", /*66*/
"cint", /*67*/
"clong", /*68*/
"symbol", /*69*/
"++a", /*70*/
"a--", /*71*/
"call", /*72*/
"call()", /*73*/
"bitfield", /*74*/
"if", /*75*/
"init", /*76*/
"loadR0", /*77*/
"divlong", /*78*/
};
char *types[] {
invalid, /*0=TYPELESS*/
"char", /*1=CHAR*/
invalid, /*2=SHORT*/
"int", /*3=INT*/
"long", /*4=LONG*/
invalid, /*5=UCHAR*/
invalid, /*6=USHORT*/
"uint", /*7=UINT*/
invalid, /*8=ULONG*/
invalid, /*9=FLOAT*/
invalid, /*10=DOUBLE*/
"struct", /*11=STRUCT*/
invalid, /*12=undefined*/
invalid, /*13=undefined*/
invalid, /*14=undefined*/
invalid, /*15=undefined*/
};
char *suvals[] {
"zero",
"one",
"quick",
"small",
"constant",
"Areg",
"Dreg",
"addressable",
"loadable",
"easy",
"hard",
};
int level;
putexpr(name,tp)
char *name;
struct tnode *tp;
{
printf("%s\n",name);
putsexpr(tp);
}
putsexpr(tp)
struct tnode *tp;
{
register struct tnode *ltp;
level++;
ltp = tp->t_left;
outlevel();
printf("%s ",opname[tp->t_op]);
if( tp->t_op == BFIELD || tp->t_op == IFGOTO ) {
if( tp->t_op == BFIELD )
printf("off=%d len=%d\n",(tp->t_su>>8)&0377,tp->t_su&0377);
else
printf("%s goto L%d\n",tp->t_type?"TRUE":"FALSE",tp->t_su);
putsexpr(tp->t_left);
level--;
return;
}
puttsu(tp);
switch( tp->t_op ) {
case DCLONG:
case CLONG:
printf(" %x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case CINT:
printf(" %d\n",tp->t_value);
break;
case AUTODEC:
case AUTOINC:
printf(" R%d\n",tp->t_reg);
break;
case SYMBOL:
switch( tp->t_sc ) {
case REGISTER:
printf(" R%d",tp->t_reg);
break;
case CINDR:
printf(" %d\n",tp->t_offset);
break;
case CLINDR:
printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
break;
case REGOFF:
printf(" %d(R%d)",tp->t_offset,tp->t_reg);
break;
case EXTERNAL:
case EXTOFF:
printf(" %s+%d",tp->t_symbol,tp->t_offset);
if( tp->t_sc == EXTOFF )
printf("(R%d)",tp->t_reg);
break;
case STATIC:
case STATOFF:
printf(" L%d+%d",tp->t_label,tp->t_offset);
if( tp->t_sc == STATOFF )
printf("(R%d)",tp->t_reg);
break;
case INDEXED:
printf(" %d(R%d,R%d)",tp->t_offset,tp->t_reg,tp->t_xreg);
break;
}
putchar('\n');
break;
case IFGOTO:
putsexpr(tp->t_left);
break;
default:
putchar('\n');
putsexpr(tp->t_left);
if( binop(tp->t_op) )
putsexpr(tp->t_right);
break;
}
level--;
}
outlevel()
{
register int i;
for( i = 0; i < level; i++ )
putchar('\t');
}
puttsu(tp)
struct tnode *tp;
{
register int i;
if( suptype(tp->t_type) )
putchar('*');
printf("%s ",types[btype(tp->t_type)]);
if( tp->t_su != 0 || (tp->t_op == CINT && tp->t_value == 0) ) {
i = tp->t_su >> 8;
if( i > 15 || i < 0 )
printf("INVALID");
else
printf("%s",suvals[tp->t_su>>8]);
}
}
#endif

View File

@@ -0,0 +1,8 @@
$ set def [steve.cpm68k.c.cgen]
$ set noon
$ lo68 -r -s -o c168.out lib:startup.o canon.o codegen.o cskels.o interf.o -
main.o optab.o putexpr.o sucomp.o tabl.o util.o initx.o lib:lib6.a
$ conv :== $bin:conv
$ conv
c168.out
[--.asc]c168.asc

View File

@@ -0,0 +1,111 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* sucomp - Sethy-Ullman expression complexity measure computation*/
/* This is a heuristic computation of the Sethy-Ullman numbers*/
/* for expressions. This gives an approximation of the complexity*/
/* of the expression. The code generation scheme works best if*/
/* the most complex expressions are done first.*/
sucomp(tp,nregs,flag) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int nregs; /* number of registers left*/
int flag; /* 1=>set values in tree, 0=>return*/
{
register int su, sur, op, i;
register struct tnode *ltp, *rtp;
nregs = dreg(nregs);
if( binop(op=tp->t_op) ) {
ltp = tp->t_left;
rtp = tp->t_right;
}
else if( unaryop(op) )
ltp = tp->t_left;
switch( op ) {
case CLONG:
if( tp->t_lvalue >= 0x8000L || tp->t_lvalue <= 0xffff8000L ) {
su = SU_ADDR;
break;
}
i = tp->t_lvalue;
case CINT:
if( op == CINT )
i = tp->t_value;
if( i == 0 )
su = SU_ZERO;
else if( i == 1 )
su = SU_ONE;
else if( i >= 1 && i <= QUICKVAL )
su = SU_SMALL;
else if( i >= -128 && i <= 127 )
su = SU_QUICK;
else
su = SU_CONST;
break;
case COMMA:
su = max(sucomp(rtp,nregs,flag),sucomp(ltp,nregs,flag));
su = max(su,SU_EASY);
break;
case ADDR:
su = sucomp(ltp,nregs,flag);
break;
case DCLONG:
case AUTOINC:
case AUTODEC:
su = SU_ADDR;
break;
case SYMBOL:
if( tp->t_sc != REGISTER )
su = SU_ADDR;
else if( isdreg(tp->t_reg) )
su = SU_REG;
else
su = SU_AREG;
break;
case LDIV:
case LEQDIV:
case LMOD:
case LEQMOD:
case CALL:
case LMULT:
case LEQMULT:
sucomp(rtp,nregs,flag);
case NACALL:
sucomp(ltp,nregs,flag);
su = SU_VHARD; /*very hard*/
break;
default:
su = sucomp(ltp,nregs,flag);
if( binop(op) ) {
if( su <= SU_ADDR )
su = max(su,sucomp(rtp,nregs,flag));
else {
sur = sucomp(rtp,nregs+1,flag);
if( sur > SU_ADDR && nregs > HICREG )
su = max(su,SU_HARD);
}
su = max(SU_EASY,su);
}
else if( su <= SU_XREG )
su = max(SU_EASY,su);
break;
}
if( flag )
tp->t_su = su;
return(su);
}

View File

@@ -0,0 +1,119 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
/*info on operators:*/
/*000077-- OPPRI - priority*/
/*000100-- OPBIN - binary operator*/
/*000200-- OPLVAL - left operand must be lvalue*/
/*000400-- OPREL - relational operator*/
/*001000-- OPASSIGN - assignment operator*/
/*002000-- OPLWORD - int required on left*/
/*004000-- OPRWORD - int required on right*/
/*010000-- OPCOM commutative*/
/*020000-- OPRAS - right associative*/
/*040000-- OPTERM - termination node*/
/*100000 - OPCONVS - conversion operator*/
int opinfo[] {
TRMPRI, /*EOF*/
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
ADDPRI|OPBIN, /*SUB - expr - expr*/
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
MULPRI|OPBIN, /*DIV - expr / expr*/
MULPRI|OPBIN, /*MOD - expr % expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
UNOPRI|OPRAS, /*UMINUS - - expr*/
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
TRMPRI, /*FJSR - generate function jsr*/
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
TRMPRI|OPCONVS, /*INT2L*/
TRMPRI|OPCONVS, /*LONG2I*/
TRMPRI|OPBIN, /*BTST*/
TRMPRI, /*LOAD*/
TRMPRI|OPBIN, /*LMULT*/
TRMPRI|OPBIN, /*LDIV*/
TRMPRI|OPBIN, /*LMOD*/
TRMPRI|OPBIN, /*LEQMULT*/
TRMPRI|OPBIN, /*LEQDIV*/
TRMPRI|OPBIN, /*LEQMOD*/
TRMPRI|ASGOP, /*EQADDR*/
TRMPRI, /*unused - 47*/
TRMPRI, /*unused - 48*/
TRMPRI, /*unused - 49*/
TRMPRI, /*unused - 50*/
TRMPRI, /*unused - 51*/
TRMPRI, /*unused - 52*/
TRMPRI, /*unused - 53*/
TRMPRI, /*unused - 54*/
TRMPRI, /*unused - 55*/
TRMPRI, /*unused - 56*/
TRMPRI, /*unused - 57*/
TRMPRI, /*unused - 58*/
TRMPRI, /*unused - 59*/
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
LNDPRI|OPBIN, /*LAND - expr && expr*/
LORPRI|OPBIN, /*LOR - expr || expr*/
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
QMKPRI|OPRAS|OPBIN, /*COLON*/
COMPRI|OPBIN, /*COMMA*/
TRMPRI|OPTERM, /*CINT*/
TRMPRI|OPTERM, /*CLONG*/
TRMPRI|OPTERM, /*SYMBOL*/
TRMPRI|OPTERM, /*AUTOINC*/
TRMPRI|OPTERM, /*AUTODEC*/
LPNPRI|OPBIN, /*CALL - call with arguments*/
LPNPRI, /*NACALL - no argument call*/
TRMPRI, /*BFIELD - field selection*/
TRMPRI, /*CONDBR*/
TRMPRI, /*INIT*/
TRMPRI, /*LOADREG*/
TRMPRI|OPTERM, /*DCLONG - divide const long*/
TRMPRI, /*unused - 79*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
TRMPRI, /*SEMI*/
TRMPRI, /*LCURBR - {*/
TRMPRI, /*RCURBR - }*/
LPNPRI, /*LBRACK - [*/
RPNPRI, /*RBRACK - ]*/
LPNPRI, /*LPAREN - )*/
RPNPRI, /*RPAREN - )*/
TRMPRI|OPTERM, /*STRING*/
TRMPRI, /*RESWORD*/
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
};

View File

@@ -0,0 +1,387 @@
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* xnalloc - allocate address-indexed node*/
char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
int type; /* data type*/
int ar; /* address register*/
int off; /* 8-bit offset*/
int xr; /* index register*/
int xt; /* index register type*/
{
register struct indexnode *xp;
xp = talloc(sizeof(*xp));
xp->t_op = SYMBOL;
xp->t_type = type;
xp->t_sc = INDEXED;
xp->t_reg = ar;
xp->t_su = SU_ADDR;
xp->t_offset = off;
xp->t_xreg = xr;
xp->t_xtype = xt;
return(xp);
}
/* tcopy - expression tree copy*/
char *tcopy(tp) /* returns ptr to copied tree*/
struct tnode *tp;
{
register char *p;
switch( tp->t_op ) {
case SYMBOL:
if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
else {
p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
p->t_label = tp->t_label;
}
p->t_offset = tp->t_offset;
p->t_reg = tp->t_reg;
return(p);
case CINT:
return(cnalloc(tp->t_type,tp->t_value));
case CLONG:
return(lcnalloc(tp->t_type,tp->t_lvalue));
case DCLONG:
p = lcnalloc(tp->t_type,tp->t_lvalue);
p->t_op = DCLONG;
return(p);
default:
if( binop(tp->t_op) )
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
tcopy(tp->t_right)));
if( unaryop(tp->t_op) )
return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
null));
error("tcopy op=%d",tp->t_op);
return(tp);
}
}
/* outaexpr - output address expression*/
outaexpr(tp,flags) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int flags; /* flags (IMMED,LOFFSET,...)*/
{
register int off, reg, lab;
long l;
if( tp->t_op == ADDR ) {
tp = tp->t_left;
putchar('#');
}
off = tp->t_offset;
reg = tp->t_reg;
lab = tp->t_label;
switch( tp->t_op ) {
case AUTOINC:
printf("(R%d)+",reg);
break;
case AUTODEC:
printf("-(R%d)",reg);
break;
case CINT:
if( flags & IMMED )
putchar('#');
printf("%d",tp->t_value);
break;
case DCLONG:
case CLONG:
if( flags & IMMED )
putchar('#');
outlval(tp->t_lvalue);
break;
case SYMBOL:
if( off ) {
switch( tp->t_sc ) {
default:
printf("%d+",off);
break;
case REGOFF:
printf("%d",off);
case CINDR:
case CLINDR:
case INDEXED:
break;
case REGISTER:
error("invalid register expression");
break;
}
}
switch( tp->t_sc ) {
case REGISTER:
printf("R%d",reg);
break;
case REGOFF:
printf("(R%d)",reg);
break;
case EXTERNAL:
printf("_%.8s",tp->t_symbol);
break;
case EXTOFF:
printf("_%.8s(R%d)",tp->t_symbol,reg);
break;
case STATIC:
printf("L%d",lab);
break;
case STATOFF:
printf("L%d(R%d)",lab,reg);
break;
case INDEXED:
printf("%d(R%d,R%d",off,reg,tp->t_xreg);
outatype(tp->t_xtype);
putchar(')');
break;
case CINDR:
printf("%d",off);
break;
/*the following will work on: PDP-11, 68000, IBM-360, VAX, etc.*/
/*it will not work on word machines or on machines where either*/
/*longs two ints or two shorts.*/
case CLINDR:
l.hiword = tp->t_offset;
l.loword = tp->t_ssp;
outlval(l);
break;
default:
error("invalid storage class %d\n",tp->t_sc);
break;
}
break;
default:
error("invalid operator %d\n",tp->t_op);
break;
}
}
/* outlval - output long value*/
/* This is a big pain because the PDP-11 doesn't do long divides*/
/* in hardware.*/
outlval(lval)
long lval;
{
char digs[8];
register int i, c;
i = 0;
do {
digs[i++] = lval & 0xf;
lval =>> 4;
lval =& 0xfffffff;
} while ( lval );
putchar('$');
while( --i >= 0 ) {
c = digs[i];
putchar(c>=10?c+('a'-10):c+'0');
}
}
/* outtype - output 68000 type (null, .b, .l) depending on data type*/
outtype(type)
int type;
{
if( longorptr(type) )
printf(".l");
else if( type == CHAR )
printf(".b");
}
/* outatype - output address type (.l or null) depending on data type*/
outatype(type)
int type;
{
if( longorptr(type) )
printf(".l");
}
/* outext - output register sign extension*/
outext(reg)
int reg;
{
printf("ext.l R%d\n",reg);
}
/* outuext - output unsigned to long register extension*/
outuext(reg)
int reg;
{
printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg);
}
/* outextend - output register extension to long depending on type*/
outextend(tp,type,reg) /* returns - none*/
struct tnode *tp; /* tree to convert from*/
int type; /* type to convert to*/
int reg; /* register to convert*/
{
if( isdreg(reg) && longorptr(tp->t_type) == 0 && longorptr(type) ) {
if( unsign(tp->t_type) )
outuext(reg);
else
outext(reg);
}
}
/* outswap - output swap register instruction*/
outswap(reg)
int reg;
{
printf("swap R%d\n",reg);
}
/* outrr - output register to register instruction*/
outrr(ins,r1,r2,tp)
char *ins;
int r1;
int r2;
struct tnode *tp;
{
printf("%s",ins);
if( isareg(r1) || isareg(r2) )
outatype(tp->t_type);
else
outtype(tp->t_type);
printf(" R%d,R%d\n",r1,r2);
}
/* outmovr - output "move[type] R1,R2" instruction*/
outmovr(r1,r2,tp)
int r1;
int r2;
struct tnode *tp;
{
if( r1 != r2 )
outrr("move",r1,r2,tp);
}
/* outaddr - output "add[type] R1,R2" instruction*/
outaddr(r1,r2,tp)
int r1;
int r2;
struct tnode *tp;
{
outrr("add",r1,r2,tp);
}
/* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
outcmpm(tp)
struct tnode *tp;
{
printf("cmpm");
outtype(tp->t_left->t_type);
printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
}
/* outcreg - output reference to compiler temp register*/
outcreg(reg)
int reg;
{
if( dreg(reg) > HICREG )
error("expression too complex");
printf("R%d",reg);
}
/* outcmp0 - output a compare with 0, special for address register*/
outcmp0(reg,tp)
int reg;
struct tnode *tp;
{
if( isareg(reg) ) {
printf("cmp");
outatype(tp->t_type);
printf(" #0,R%d\n",reg);
}
else {
printf("tst");
outtype(tp->t_type);
printf(" R%d\n",reg);
}
}
/* outrpush - output "move[type] R1,[-](sp)"*/
outrpush(reg,tp,pflag)
int reg;
struct tnode *tp;
int pflag;
{
printf("move");
outatype(tp->t_type);
printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
}
/* popstack - output instruction to pop stack desired number of bytes*/
/* Makes use of special case instructions to save a word.*/
popstack(nb) /* returns - none*/
int nb; /* number of bytes to pop*/
{
if( nb > 0 )
printf("add #%d,sp\n",nb);
}
/* cenalloc - code generator external node allocation*/
/* This may be coalesced into enalloc in parser.*/
char *cenalloc(type,sc,sym) /* returns ptr to node alloced*/
int type; /* type of symbol*/
int sc; /* storage class*/
char *sym; /* symbol name*/
{
register struct extnode *ep;
ep = talloc(sizeof(*ep));
ep->t_op = SYMBOL;
ep->t_type = type;
ep->t_sc = sc;
ep->t_su = 0;
ep->t_offset = 0;
symcopy(sym,ep->t_symbol);
return(ep);
}
/* outccsave - output instruction to move cc's to register.*/
outccsave(reg)
int reg;
{
printf("move sr,R%d\n",reg);
}
/* outccrestore - output instruction to restore cc's from register*/
outccrestore(reg)
int reg;
{
printf("move R%d,ccr\n",reg);
}

View File

@@ -0,0 +1,14 @@
$ set def [steve.cpm68k.c.cgen]
$ !
$ cx CANON
$ cx CODEGEN
$ cx CSKELS
$ cx INIT
$ cx INTERF
$ cx MAIN
$ cx OPTAB
$ cx PUTEXPR
$ cx SUCOMP
$ cx TABL
$ cx UTIL
$ @vrelink

View File

@@ -0,0 +1,3 @@
$ set def [steve.cpm68k.c.cgen]
$ clink canon,codegen,cskels,init,interf,main,optab,putexpr,sucomp,tabl,util,-
lib:k3/lib c168'p1'