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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,196 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include <stdio.h>
#include <klib.h>
#undef putchar
#define putchar xputchar
#undef ferror
#define ferror xferror
#define printf xprintf
#include "icode.h"
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 *fpcnalloc();
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 isfloat(type) (type==FLOAT)
#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 NOTLOFFSET 0
/* one line routines turned into defines [vlh] for speed */
/*outgoto - output "bra L[labno]"*/
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
/*outlab - output "L[labno]:"*/
#define outlab(lab) if (lab>0) printf("L%d:",lab)
/*outext - output register sign extension*/
#define outext(reg) printf("ext.l R%d\n",reg)
/*outuext - output unsigned to long register extension*/
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
/*outswap - output swap register instruction*/
#define outswap(reg) printf("swap R%d\n",reg)
/*outaddr - output "add [type] R1 R2" instruction*/
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
/*outccsave - ouput instruction to move cc's to register*/
#define outccsave(reg) printf("move sr,R%d\n",reg)
/*outccrestore - output instruction to restore cc's from register*/
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
/*basetype - get the btype info sans unsigned*/
#define basetype(type) ((type==UNSIGNED) ? INT : type)
#define unsign(type) ((type) == UNSIGNED)
#define longorptr(type) (type==LONG || (type&SUPTYP))
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
#define dreg(reg) ((reg) & (~AREGLO))
#define areg(reg) ((reg) | AREGLO)
#define isareg(reg) ((reg) >= AREGLO)
#define isdreg(reg) ((reg) < AREGLO)
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)

View File

@@ -0,0 +1,200 @@
1File: CGEN.H Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include <stdio.h>
9 #include <klib.h>
10 #undef putchar
11 #define putchar xputchar
12 #undef ferror
13 #define ferror xferror
14 #define printf xprintf
15 #include "icode.h"
16
17 char brtab[][2];
18 int invrel[];
19 int swaprel[];
20 char *strtab[];
21 char null[];
22
23 /*operator tree node for unary and binary operators*/
24 struct tnode {
25 int t_op; /*operator*/
26 int t_type; /*data type of result*/
27 int t_su; /*Sethy-Ullman number*/
28 int t_ssp;
29 struct tnode *t_left; /*left sub-tree*/
30 struct tnode *t_right; /*right sub-tree (undefined if unary)*/
31 };
32
33 /*constant terminal node*/
34 struct conode {
35 int t_op; /*operator*/
36 int t_type; /*type*/
37 int t_su; /*Sethy-Ullman number*/
38 int t_ssp;
39 int t_value; /*value or label number*/
40 };
41
42 struct lconode {
43 int t_op; /*operator*/
44 int t_type; /*type*/
45 int t_su; /*Sethy-Ullman number*/
46 int t_ssp;
47 long t_lvalue; /*value or label number*/
48 };
49
50 /*local symbol terminal node*/
51 struct symnode {
52 int t_op; /*operator*/
53 int t_type; /*symbol data type*/
54 int t_su; /*Sethy-Ullman number*/
55 int t_ssp;
56 int t_sc; /*storage class*/
57 int t_offset; /*register offset*/
58 int t_reg; /*register number*/
59 int t_label; /*label number if static*/
1File: CGEN.H Page 2
60 };
61
62 /*external symbol reference node*/
63 struct extnode {
64 int t_op; /*operator*/
65 int t_type; /*symbol data type*/
66 int t_su; /*Sethy-Ullman number*/
67 int t_ssp;
68 int t_sc; /*storage class*/
69 int t_offset; /*register offset*/
70 int t_reg; /*register number*/
71 char t_symbol[SSIZE]; /*symbol name*/
72 };
73
74 /*68000 special - indexed symbol node*/
75 /*this is used to generate a An(off,Xn.type) address*/
76 struct indexnode {
77 int t_op;
78 int t_type;
79 int t_su;
80 int t_ssp;
81 int t_sc;
82 int t_offset;
83 int t_reg;
84 int t_xreg;
85 int t_xtype;
86 };
87
88 int lflag;
89 int dflag;
90 int mflag;
91 int cflag;
92 int eflag;
93 int fflag;
94 int oflag;
95 struct io_buf ibuf, obuf;
96 int lineno;
97 int naregs;
98 int ndregs;
99 int errcnt;
100 int opinfo[];
101 int nextlabel;
102 char null[];
103 char optab[][6];
104 char *mnemonics[];
105 char *codeskels[];
106 int stacksize;
107
108 char *tnalloc();
109 char *snalloc();
110 char *cenalloc();
111 char *xnalloc();
112 char *talloc();
113 char *cnalloc();
114 char *lcnalloc();
115 char *fpcnalloc();
116 char *canon();
117 char *commute();
118 char *constant();
1File: CGEN.H Page 3
119 char *match();
120 char *addptree();
121 char *fixbfield();
122 char *coffset();
123 char *tcopy();
124
125 #define wallign(add) ((add+1)&(~1))
126 #define array(type) ((type&SUPTYP)==ARRAY)
127 #define function(type) ((type&SUPTYP)==FUNCTION)
128 #define pointer(type) ((type&SUPTYP)==POINTER)
129 #define notarray(type) ((type&SUPTYP)!=ARRAY)
130 #define notfunction(type) ((type&SUPTYP)!=FUNCTION)
131 #define notpointer(type) ((type&SUPTYP)!=POINTER)
132 #define isfloat(type) (type==FLOAT)
133 #define btype(type) (type&TYPE)
134 #define suptype(type) (type&SUPTYP)
135 #define alltype(type) (type&(SUPTYP|TYPE))
136 #define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
137 #define relop(op) ((opinfo[op]&OPREL)!=0)
138 #define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
139 #define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
140 #define rasop(op) ((opinfo[op]&OPRAS)!=0)
141 #define binop(op) ((opinfo[op]&OPBIN)!=0)
142 #define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
143 #define leafop(op) ((opinfo[op]&OPTERM)!=0)
144 #define notleafop(op) ((opinfo[op]&OPTERM)==0)
145 #define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
146 #define oppriority(op) (opinfo[op]&OPPRI)
147 #define commop(op) ((opinfo[op]&OPCOM)!=0)
148 #define convop(op) ((opinfo[op]&OPCONVS)!=0)
149 #define notconvop(op) ((opinfo[op]&OPCONVS)==0)
150 #define max(a,b) (a>b?a:b)
151 #define min(a,b) (a<b?a:b)
152
153 #define QUICKVAL 8
154 #define LEP 14
155 #define FORCC 1
156 #define FOREFF 2
157 #define FORSTACK 3
158 #define FORCREG 4
159 #define FORSP 5
160 #define FORREG 4
161 #define HICREG 2
162 #define NCREGS 3
163 #define AREGLO 8
164 #define IMMED 1
165 #define NOTIMMED 0
166 #define NOTLOFFSET 0
167
168 /* one line routines turned into defines [vlh] for speed */
169
170 /*outgoto - output "bra L[labno]"*/
171 #define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
172 /*outlab - output "L[labno]:"*/
173 #define outlab(lab) if (lab>0) printf("L%d:",lab)
174
175 /*outext - output register sign extension*/
176 #define outext(reg) printf("ext.l R%d\n",reg)
177 /*outuext - output unsigned to long register extension*/
1File: CGEN.H Page 4
178 #define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
179 /*outswap - output swap register instruction*/
180 #define outswap(reg) printf("swap R%d\n",reg)
181 /*outaddr - output "add [type] R1 R2" instruction*/
182 #define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
183 /*outccsave - ouput instruction to move cc's to register*/
184 #define outccsave(reg) printf("move sr,R%d\n",reg)
185 /*outccrestore - output instruction to restore cc's from register*/
186 #define outccrestore(reg) printf("move R%d,ccr\n",reg)
187 /*basetype - get the btype info sans unsigned*/
188 #define basetype(type) ((type==UNSIGNED) ? INT : type)
189 #define unsign(type) ((type) == UNSIGNED)
190 #define longorptr(type) (type==LONG || (type&SUPTYP))
191 #define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
192 #define dreg(reg) ((reg) & (~AREGLO))
193 #define areg(reg) ((reg) | AREGLO)
194 #define isareg(reg) ((reg) >= AREGLO)
195 #define isdreg(reg) ((reg) < AREGLO)
196 #define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)

View File

@@ -0,0 +1,756 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "cgen.h"
#include "cskel.h"
/* scodegen - over-all code generation for expression*/
/* Picks off post-fix ++, --.*/
scodegen(tp,cookie,reg) /* returns register result is in*/
struct tnode *tp;
int cookie;
int reg;
{
struct tnode *clist[20];
struct tnode **clp;
register struct tnode **cp;
register int r;
register int ccflag;
register struct tnode *rtp;
if( tp->t_op == COMMA ) {
scodegen(tp->t_left,FOREFF,reg);
return(scodegen(tp->t_right,cookie,reg));
}
ccflag = 0;
clp = clist;
tp = addptree(tp,&clp);
if( clp > clist ) {
/*
* post ++, -- in tree. We need to compile the tree post operators
* then generate code to do the post operators, then do any fix up of
* condition codes since the Stupid 68000 architect was a nimnul.
*/
if( cookie == FORCC ) {
/*
* here we make the observation that if we are comparing something with
* zero OR the top operator of the tree is not a comparison operator,
* we can compile the tree to a register, and then set the condition
* codes OK with a tst instruction at the end.
*/
if( relop(tp->t_op) ) {
if( (rtp=constant(tp->t_right)) && !rtp->t_value ) {
ccflag = 1;
tp = tp->t_left;
cookie = FORREG;
}
else
ccflag = 2;
}
else {
ccflag = 1;
cookie = FORREG;
}
}
}
r = codegen(tp,cookie,reg);
if( clp > clist ) {
if( ccflag == 2 )
outccsave(r);
for( cp = clist; cp < clp; cp++ )
codegen(*cp,FOREFF,r+1);
if( ccflag == 1 )
outcmp0(r,tp);
else if( ccflag == 2 )
outccrestore(r);
}
return(r);
}
/* addptree - prune off postfix ++, -- from expression tree*/
/* This prunes off ++, -- and collects those expressions for*/
/* scodegen.*/
char *addptree(tp,clp) /* returns pointer to pruned tree*/
struct tnode *tp;
struct tnode ***clp;
{
register int op;
op = tp->t_op;
if( leafop(op) || op == QMARK ) /* [vlh] 4.0 QMARK... */
return(tp);
if( op == POSTINC || op == POSTDEC ) {
*(*clp)++ = tp;
return( tcopy(tp->t_left) );
}
if( binop(op) )
tp->t_right = addptree(tp->t_right,clp);
tp->t_left = addptree(tp->t_left,clp);
return(tp);
}
/* codegen - generate code for expression*/
/* This calls up rcodegen, which prunes off any special register*/
/* optimization code, then calls ucodegen (unrecursive) code*/
/* generation.*/
codegen(tp,cookie,reg) /* returns reg result is in*/
struct tnode *tp; /* tree pointer*/
int cookie; /* code generation goals*/
int reg; /* first available register*/
{
register int size, savestk, ssize, r, i, scookie;
register struct tnode *rtp;
#ifndef NODEBUG
if( cflag )
printf("codegen op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
#endif
switch( tp->t_op ) {
case CALL:
case NACALL:
ssize = 0;
savestk = stacksize;
if( tp->t_left->t_op != SYMBOL )
stacksize++;
if( tp->t_op == CALL ) {
rtp = tp->t_right;
while( rtp->t_op == COMMA ) {
ssize =+ dofarg(rtp->t_right);
rtp = rtp->t_left;
}
ssize =+ dofarg(rtp);
}
tp->t_op = FJSR; /*generate JSR (unary op)*/
codegen(tp,FORREG,reg);
popstack(ssize);
stacksize = savestk;
fixresult(tp,cookie,0);
return(0); /*result in R0*/
case COMMA:
codegen(tp->t_left,FOREFF,reg);
return(codegen(tp->t_right,cookie,reg));
case AND:
if( cookie == FORCC && (i=isonebit(tp->t_right)) >= 0 &&
(i=dobitadd(tp->t_left,i)) >= 0 ) {
if( convop(tp->t_right->t_op) )
tp->t_right = tp->t_right->t_left;
tp->t_right->t_value = i;
tp->t_op = BTST;
tp = canon(tp);
sucomp(tp,reg,1);
}
break;
}
if( rcodegen(&tp,cookie,reg) ) {
if( cookie == FORCC && tp->t_op == SYMBOL && tp->t_sc == REGISTER
&& isdreg(tp->t_reg))
return(reg);
}
r = ucodegen(tp,cookie,reg);
return(r);
}
/* fixresult - fix result of code generation*/
fixresult(tp,cookie,reg) /* returns - none*/
struct tnode *tp;
int cookie; /* wanted this cookie*/
int reg;
{
#ifndef NODEBUG
if (cflag)
printf("fixresult cookie=%d reg=%d op=%d\n",cookie,reg,tp->t_op);
#endif
switch( cookie ) {
case FORCC:
outcmp0(reg,tp);
break;
case FORSP:
case FORSTACK:
stacksize++;
outrpush(reg,tp,cookie==FORSTACK);
break;
}
return(reg);
}
/* ucodegen - generate code for tree given cookie and starting register*/
/* Handles the matching of the expression tree node with the*/
/* corresponding code generation table. When a match is found,*/
/* expand is called to expand the code skeleton macro.*/
ucodegen(tp,cookie,reg) /* returns reg result is in*/
struct tnode *tp; /* pointer to expression tree*/
int cookie; /* (FORCC,FOREFF,FORREG,FORSTACK)*/
int reg; /* first available register*/
{
register int r;
register char *p;
#ifndef NODEBUG
if(cflag)
putexpr("ucodegen",tp);
#endif
switch( tp->t_op ) {
case STASSIGN: /*[vlh]*/
outstrcpy(codegen(tp->t_left,FORREG,areg(reg)),
codegen(tp->t_right,FORREG,areg(reg+1)), tp->t_type);
return(reg);
break;
case SYMBOL:
if( cookie == FOREFF )
return(reg);
break;
case LSH:
if( (isareg(reg)) && (p=constant(tp->t_right)) &&
!(unsign(tp->t_left->t_type)) &&
(p->t_value == 1 || p->t_value == 2) ) {
r = codegen(tp->t_left,FORREG,reg);
outmovr(r,reg,tp->t_left);
if( p->t_value == 2 )
outaddr(reg,reg,tp);
outaddr(reg,reg,tp);
fixresult(tp,cookie,reg);
return(reg);
}
break;
case EQMULT:
case EQDIV:
case LEQMULT:
case LEQDIV:
case EQMOD:
case LEQMOD:
case EQRSH:
case EQLSH:
case EQAND:
case EQOR:
case EQXOR:
if( indexreg(tp->t_left) ) {
reg = dreg(reg);
outmovr(r=tp->t_left->t_reg,reg,tp);
tp->t_left->t_reg = reg;
codegen(tp,cookie,reg+1);
outmovr(reg,r,tp);
return(reg);
}
break;
case ADD:
case EQADD:
if( (p=constant(tp->t_right)) && p->t_value < 0 &&
p->t_value >= -QUICKVAL ) {
p->t_value = - p->t_value;
tp->t_op =+ (SUB-ADD);
}
break;
}
sucomp(tp,reg,1);
if( (r=loadexpr(tp,cookie,reg)) >= 0 )
return(r);
if( (r=cqmark(tp,cookie,reg)) >= 0 )
return(r);
if( (r=hardrel(tp,cookie,reg)) >= 0 )
return(r);
if( cookie == FORCC && (p=match(tp,FOREFF,reg)) != 0 ) {
r = expand(tp,FOREFF,reg,p);
if( asgop(tp->t_op) && indexreg(tp->t_left) )
outcmp0(tp->t_left->t_reg,tp->t_left);
}
else if( p = match(tp,cookie,reg) )
r = expand(tp,cookie,reg,p);
else if( cookie != FORREG )
r = fixresult(tp,cookie,ucodegen(tp,FORREG,reg));
else
error("no code table for %d",tp->t_op);
return(r);
}
/* outstrcpy - output structure copy */
outstrcpy(lr,rr,size) /*[vlh]*/
int lr, rr; /* left register, right register */
int size; /* structure size to copy */
{
register int lab;
lab = nextlabel++;
printf("move #%d,r%d\n",(size/2)-1,dreg(lr));
outlab(lab);
printf("move (r%d)+,(r%d)+\ndbra r%d,L%d\n",rr,lr,dreg(lr),lab);
}
/* loadexpr - load an addressable expression into a register*/
/* This checks for any possible usage of the register indexed*/
/* addressing mode. Note that this relies on the good graces of the*/
/* load code skeletons not to muck up the compiler registers before*/
/* loading an addressable expression...*/
loadexpr(tp,cookie,reg) /* returns register loaded or -1*/
struct tnode *tp; /* pointer to expression tree*/
int reg; /* register to load*/
{
register struct tnode *rtp, *ltp, *xtp, *atp;
register int off, r, type, nr, ar, xr, xt;
if( tp->t_op == INDR || LOADABLE(tp) ) {
type = tp->t_type;
if( tp->t_op == INDR && (ltp=tp->t_left)->t_op == ADD ) {
rtp = ltp->t_right;
ltp = ltp->t_left;
off = 0;
if( rtp->t_op == CINT && ((off=rtp->t_value) < -128 ||
off > 127 || ltp->t_op != ADD ) ) {
tp = snalloc(type,AUTO,off,0,0);
if( indexreg(ltp) )
tp->t_reg = ltp->t_reg;
else {
r = codegen(ltp,FORREG,areg(reg));
if( isdreg(r) )
outmovr(r,areg(r),ltp);
tp->t_reg = areg(r);
}
}
else {
if( rtp->t_op == CINT ) {
rtp = ltp->t_right;
ltp = ltp->t_left;
}
if(indexreg(rtp) || (!(indexreg(ltp)) && (isreg(rtp)))) {
xtp = ltp;
ltp = rtp;
rtp = xtp;
}
xtp = atp = 0;
if( indexreg(ltp) ) {
ar = ltp->t_reg;
if( (isreg(rtp)) && rtp->t_type != CHAR ) {
xr = rtp->t_reg;
xt = rtp->t_type;
}
else
xtp = rtp;
}
else if( (isreg(ltp)) && ltp->t_type != CHAR &&
(lflag || rtp->t_op != ADDR) ) {
xr = ltp->t_reg;
xt = ltp->t_type;
atp = rtp;
}
else if( rtp->t_op == ADDR ) {
atp = ltp;
xtp = rtp;
}
else {
atp = rtp;
xtp = ltp;
}
nr = 0;
if( atp )
nr++;
if( xtp && (xtp->t_op != ADDR || lflag ) )
nr++;
if( dreg(nr+reg) <= HICREG ) {
r = reg;
if( atp ) {
ar = codegen(atp,FORREG,areg(r));
if( isdreg(ar) ) {
outmovr(ar,areg(ar),atp);
ar = areg(ar);
}
r++;
}
if( xtp && xtp->t_op == ADDR && !lflag ) {
tp = xtp->t_left;
tp->t_sc =+ (EXTOFF-EXTERNAL);
tp->t_offset =+ off;
tp->t_reg = ar;
}
else {
if( xtp ) {
xr = codegen(xtp,FORREG,areg(r));
xt = xtp->t_type;
}
tp = xnalloc(type,ar,off,xr,xt);
}
}
}
}
if( (isareg(reg)) && tp->t_type == CHAR )
reg = dreg(reg);
tp = tnalloc(LOAD,tp->t_type,SU_EASY,0,tp,null);
return( codegen(tp,cookie,reg) );
}
return(-1);
}
/* coffset - check offset for addressable node*/
char *coffset(tp) /* returns ptr to const off node*/
struct tnode *tp; /* pointer to node*/
{
register struct tnode *rtp;
if( tp->t_op == ADD ) {
rtp = tp->t_right;
if( rtp->t_op == CINT )
return(rtp);
if(!lflag) {
if( rtp->t_op == ADDR )
return(rtp->t_left);
rtp = tp->t_left;
if( rtp->t_op == ADDR ) {
tp->t_left = tp->t_right;
tp->t_right = rtp;
return(rtp->t_left);
}
}
}
return(0);
}
/* hardrel - do relationals returning a value*/
hardrel(tp,cookie,reg) /* returns reg or -1*/
struct tnode *tp; /* pointer to tree*/
int cookie; /* cookie for code generation*/
int reg; /* low register*/
{
char *p;
int op, lab1, lab2;
if( cookie != FORCC && (relop(op=tp->t_op) || op == LOR ||
op == LAND || op == NOT) ) {
lab1 = nextlabel++;
condbr(tp,TRUE,lab1,reg);
p = canon(cnalloc(INT,0));
codegen(p,cookie,reg);
lab2 = nextlabel++;
outgoto(lab2);
outlab(lab1);
p = canon(cnalloc(INT,1));
codegen(p,cookie,reg);
outlab(lab2);
return(reg);
}
return(-1);
}
/* cqmark - compile question mark operator*/
/* This does the compilation of the question mark operator.*/
cqmark(tp,cookie,reg) /* returns reg or -1*/
struct tnode *tp;
int cookie;
int reg;
{
register int lab1, lab2, savestk, r;
if( tp->t_op == QMARK && cookie != FORCC ) {
lab1 = nextlabel++;
condbr(tp->t_left,FALSE,lab1,reg);
savestk = stacksize;
r = scodegen(tp->t_right->t_left,cookie,reg); /* [mc] 4.0 */
outmovr(r,reg,tp);
stacksize = savestk;
outgoto(lab2=nextlabel++);
outlab(lab1);
r = scodegen(tp->t_right->t_right,cookie,reg); /* [mc] 4.0 */
outmovr(r,reg,tp);
outlab(lab2);
return(reg);
}
return(-1);
}
/* condbr - handle conditional branch code generation*/
/* This handles the conditional branch code generation, handling*/
/* the special cases for constants, ||, &&, ! and generating the*/
/* correct conditional branch instruction.*/
condbr(tp,dir,lab,reg)
struct tnode *tp;
int dir;
int lab;
int reg;
{
register struct tnode *ltp, *rtp;
register int lab1, optype, op, subdir;
ltp = tp->t_left;
if( binop(op=tp->t_op) )
rtp = tp->t_right;
subdir = dir; /*set up for LOR*/
switch( op ) {
case CINT:
if( !tp->t_value ) {
if( dir == FALSE )
outgoto(lab);
}
else if( dir != FALSE )
outgoto(lab);
break;
case NOT:
condbr(ltp,!dir,lab,reg);
break;
case LAND:
dir = !dir;
case LOR:
if( dir == FALSE ) {
lab1 = nextlabel++;
condbr(ltp,!subdir,lab1,reg);
condbr(rtp,subdir,lab,reg);
outlab(lab1);
}
else {
condbr(ltp,subdir,lab,reg);
condbr(rtp,subdir,lab,reg);
}
break;
case COMMA:
scodegen(tp->t_left,FOREFF,reg);
condbr(tp->t_right,dir,lab,reg);
break;
default:
if( op == NEQUALS && ltp->t_op == PREDEC &&
isdreg(ltp->t_left->t_reg) && ltp->t_left->t_type == INT &&
rtp->t_op == CINT && rtp->t_value == -1 ) {
outdbra(ltp->t_left->t_reg,lab);
break;
}
if( relop(op) && ltp->t_op == AUTOINC && rtp->t_op == AUTOINC &&
ltp->t_type == rtp->t_type )
outcmpm(tp);
else
scodegen(tp,FORCC,reg);
optype = 0;
if( relop(op) ) {
if( unorptr(ltp->t_type) || unorptr(rtp->t_type) )
optype =+ 1;
}
else
op = NEQUALS;
if(!dir)
op = invrel[op-EQUALS];
optype = brtab[op-EQUALS][optype];
printf("%s L%d\n",mnemonics[optype],lab);
break;
}
}
rcodegen(tpp,cookie,reg) /* returns changed flag*/
struct tnode **tpp; /* pointer to tree*/
int cookie; /* code generation cookie*/
int reg; /* register to use for code*/
{
register int change, op;
register struct tnode *tp;
tp = *tpp;
op = tp->t_op;
change = 0;
if( notleafop(op) && op != COMMA ) {
change =+ rcodegen(&tp->t_left,cookie,reg);
if( binop(op) )
change =+ rcodegen(&tp->t_right,cookie,reg);
change =+ rcgen(tpp,cookie,reg);
}
if( change )
*tpp = canon(*tpp);
return(change);
}
rcgen(tpp,cookie,reg) /* returns changed flag*/
struct tnode **tpp; /* pointer to tree*/
int cookie; /* code generation goals*/
int reg; /* register to use*/
{
register struct tnode *tp, *p, *ltp, *rtp;
register int op, change;
change = 0;
for( tp = *tpp ; binop(op=tp->t_op); *tpp=tp=canon(tp), change++ ) {
ltp = tp->t_left;
if( ltp->t_op != SYMBOL )
break;
rtp = tp->t_right;
switch( op ) {
case ASSIGN:
if( ltp->t_sc != REGISTER )
return(change);
switch( rtp->t_op ) {
case MULT:
case DIV:
case MOD:
case AND:
case OR:
case XOR:
case LSH:
case RSH:
if( isareg(ltp->t_reg) )
return(change);
case ADD:
case SUB:
p = rtp->t_right;
if(NOTADDRESSABLE(ltp) || !noref(rtp->t_right,ltp->t_reg))
return(change);
p = rtp->t_left;
if( p->t_op != SYMBOL || p->t_sc != REGISTER ||
p->t_reg != ltp->t_reg ) {
tp->t_right = p;
#ifndef NODEBUG
if( cflag > 1 )
putexpr("rcgen",tp);
#endif
codegen(tp,FOREFF,reg);
}
tp->t_right = rtp->t_right;
tp->t_op = rtp->t_op + (EQADD-ADD);
continue;
}
case EQLSH:
case EQRSH:
if( ltp->t_sc != REGISTER )
return(change);
case EQADD:
case EQSUB:
case EQAND:
case EQOR:
case EQXOR:
if( ltp->t_type == CHAR )
return(change);
#ifndef NODEBUG
if( cflag > 1 )
putexpr("rcgen",tp);
#endif
ucodegen(tp,FOREFF,reg);
tp = ltp;
continue;
case PREDEC:
case PREINC:
if( cookie == FORCC || ltp->t_type == CHAR )
return(change);
ucodegen(tp,FOREFF,reg);
tp = ltp;
continue;
}
break;
}
return(change);
}
noref(tp,reg) /* 4.0 change */
struct tnode *tp; /* returns 1 if no reference in tree to reg */
int reg;
{
if ( leafop(tp->t_op) ) {
if (tp->t_op == SYMBOL && tp->t_sc == REGISTER && tp->t_reg == reg)
return(0);
return(1);
}
if ( !noref(tp->t_left,reg) )
return(0);
if (binop(tp->t_op))
return( noref(tp->t_right,reg) );
return(1);
}
/* cdsize - compute size of data item*/
cdsize(tp) /* returns data size in bytes*/
struct tnode *tp;
{
register int type;
type = tp->t_type;
if( suptype(type) )
return(PTRSIZE);
switch( type ) {
case CHAR:
case INT:
case UNSIGNED:
return(INTSIZE);
case LONG:
case FLOAT: /* [vlh] 3.4 */
return(LONGSIZE);
}
error("cdsize: invalid type %d",type);
return(0);
}
dofarg(tp) /* returns number of bytes pushed*/
struct tnode *tp; /* pointer to expression tree*/
{
register int nb;
nb = 0;
if( tp->t_op == SYMBOL && tp->t_sc == STRUCT )
error("structure operation not implemented");
else if( stacksize ) {
codegen(tp,FORSTACK,0);
nb = cdsize(tp);
}
else
codegen(tp,FORSP,0);
return( nb );
}
/* dobitadd - do bit operation address checking and fixup*/
dobitadd(tp,bitno) /* returns -1 if can't or bitno*/
struct tnode *tp;
int bitno;
{
register int offset;
if( tp->t_type == CHAR )
offset = 0;
else
offset = cdsize(tp) - (bitno/BITSPBYTE) - 1;
if( tp->t_op == SYMBOL ) {
switch( tp->t_sc ) {
case REGISTER:
if( isdreg(tp->t_reg) )
return(bitno);
default:
return(-1);
case EXTERNAL:
case STATIC:
case REGOFF:
case STATOFF:
case EXTOFF:
tp->t_offset =+ offset;
return( bitno % BITSPBYTE );
}
}
else if( tp->t_op == INDR ) {
tp->t_left = tnalloc(ADD,tp->t_left->t_type,0,0,tp->t_left,
cnalloc(INT,offset));
return( bitno % BITSPBYTE );
}
return(-1);
}
isonebit(tp) /* returns -1 if not 1 bit, else bitno*/
struct tnode *tp; /* pointer to tree*/
{
if( tp = constant(tp) )
return( onebit(tp->t_value) );
return(-1);
}

View File

@@ -0,0 +1,769 @@
1File: CODEGEN.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9 #include "cskel.h"
10
11
12 /* scodegen - over-all code generation for expression*/
13 /* Picks off post-fix ++, --.*/
14 scodegen(tp,cookie,reg) /* returns register result is in*/
15 struct tnode *tp;
16 int cookie;
17 int reg;
18 {
19 struct tnode *clist[20];
20 struct tnode **clp;
21 register struct tnode **cp;
22 register int r;
23 register int ccflag;
24 register struct tnode *rtp;
25
26 if( tp->t_op == COMMA ) {
27 scodegen(tp->t_left,FOREFF,reg);
28 return(scodegen(tp->t_right,cookie,reg));
29 }
30 ccflag = 0;
31 clp = clist;
32 tp = addptree(tp,&clp);
33 if( clp > clist ) {
34 /*
35 * post ++, -- in tree. We need to compile the tree post operators
36 * then generate code to do the post operators, then do any fix up of
37 * condition codes since the Stupid 68000 architect was a nimnul.
38 */
39 if( cookie == FORCC ) {
40 /*
41 * here we make the observation that if we are comparing something with
42 * zero OR the top operator of the tree is not a comparison operator,
43 * we can compile the tree to a register, and then set the condition
44 * codes OK with a tst instruction at the end.
45 */
46 if( relop(tp->t_op) ) {
47 if( (rtp=constant(tp->t_right)) && !rtp->t_value ) {
48 ccflag = 1;
49 tp = tp->t_left;
50 cookie = FORREG;
51 }
52 else
53 ccflag = 2;
54 }
55 else {
56 ccflag = 1;
57 cookie = FORREG;
58 }
59 }
1File: CODEGEN.C Page 2
60 }
61 r = codegen(tp,cookie,reg);
62 if( clp > clist ) {
63 if( ccflag == 2 )
64 outccsave(r);
65 for( cp = clist; cp < clp; cp++ )
66 codegen(*cp,FOREFF,r+1);
67 if( ccflag == 1 )
68 outcmp0(r,tp);
69 else if( ccflag == 2 )
70 outccrestore(r);
71 }
72 return(r);
73 }
74
75 /* addptree - prune off postfix ++, -- from expression tree*/
76 /* This prunes off ++, -- and collects those expressions for*/
77 /* scodegen.*/
78 char *addptree(tp,clp) /* returns pointer to pruned tree*/
79 struct tnode *tp;
80 struct tnode ***clp;
81 {
82 register int op;
83
84 op = tp->t_op;
85 if( leafop(op) || op == QMARK ) /* [vlh] 4.0 QMARK... */
86 return(tp);
87 if( op == POSTINC || op == POSTDEC ) {
88 *(*clp)++ = tp;
89 return( tcopy(tp->t_left) );
90 }
91 if( binop(op) )
92 tp->t_right = addptree(tp->t_right,clp);
93 tp->t_left = addptree(tp->t_left,clp);
94 return(tp);
95 }
96
97 /* codegen - generate code for expression*/
98 /* This calls up rcodegen, which prunes off any special register*/
99 /* optimization code, then calls ucodegen (unrecursive) code*/
100 /* generation.*/
101 codegen(tp,cookie,reg) /* returns reg result is in*/
102 struct tnode *tp; /* tree pointer*/
103 int cookie; /* code generation goals*/
104 int reg; /* first available register*/
105 {
106 register int size, savestk, ssize, r, i, scookie;
107 register struct tnode *rtp;
108
109 #ifndef NODEBUG
110 if( cflag )
111 printf("codegen op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
112 #endif
113 switch( tp->t_op ) {
114
115 case CALL:
116 case NACALL:
117 ssize = 0;
118 savestk = stacksize;
1File: CODEGEN.C Page 3
119 if( tp->t_left->t_op != SYMBOL )
120 stacksize++;
121 if( tp->t_op == CALL ) {
122 rtp = tp->t_right;
123 while( rtp->t_op == COMMA ) {
124 ssize =+ dofarg(rtp->t_right);
125 rtp = rtp->t_left;
126 }
127 ssize =+ dofarg(rtp);
128 }
129 tp->t_op = FJSR; /*generate JSR (unary op)*/
130 codegen(tp,FORREG,reg);
131 popstack(ssize);
132 stacksize = savestk;
133 fixresult(tp,cookie,0);
134 return(0); /*result in R0*/
135
136 case COMMA:
137 codegen(tp->t_left,FOREFF,reg);
138 return(codegen(tp->t_right,cookie,reg));
139
140 case AND:
141 if( cookie == FORCC && (i=isonebit(tp->t_right)) >= 0 &&
142 (i=dobitadd(tp->t_left,i)) >= 0 ) {
143 if( convop(tp->t_right->t_op) )
144 tp->t_right = tp->t_right->t_left;
145 tp->t_right->t_value = i;
146 tp->t_op = BTST;
147 tp = canon(tp);
148 sucomp(tp,reg,1);
149 }
150 break;
151 }
152 if( rcodegen(&tp,cookie,reg) ) {
153 if( cookie == FORCC && tp->t_op == SYMBOL && tp->t_sc == REGISTER
154 && isdreg(tp->t_reg))
155 return(reg);
156 }
157 r = ucodegen(tp,cookie,reg);
158 return(r);
159 }
160
161 /* fixresult - fix result of code generation*/
162 fixresult(tp,cookie,reg) /* returns - none*/
163 struct tnode *tp;
164 int cookie; /* wanted this cookie*/
165 int reg;
166 {
167 #ifndef NODEBUG
168 if (cflag)
169 printf("fixresult cookie=%d reg=%d op=%d\n",cookie,reg,tp->t_op);
170 #endif
171 switch( cookie ) {
172
173 case FORCC:
174 outcmp0(reg,tp);
175 break;
176
177 case FORSP:
1File: CODEGEN.C Page 4
178 case FORSTACK:
179 stacksize++;
180 outrpush(reg,tp,cookie==FORSTACK);
181 break;
182
183 }
184 return(reg);
185 }
186
187 /* ucodegen - generate code for tree given cookie and starting register*/
188 /* Handles the matching of the expression tree node with the*/
189 /* corresponding code generation table. When a match is found,*/
190 /* expand is called to expand the code skeleton macro.*/
191 ucodegen(tp,cookie,reg) /* returns reg result is in*/
192 struct tnode *tp; /* pointer to expression tree*/
193 int cookie; /* (FORCC,FOREFF,FORREG,FORSTACK)*/
194 int reg; /* first available register*/
195 {
196 register int r;
197 register char *p;
198
199 #ifndef NODEBUG
200 if(cflag)
201 putexpr("ucodegen",tp);
202 #endif
203 switch( tp->t_op ) {
204
205 case STASSIGN: /*[vlh]*/
206 outstrcpy(codegen(tp->t_left,FORREG,areg(reg)),
207 codegen(tp->t_right,FORREG,areg(reg+1)), tp->t_type);
208 return(reg);
209 break;
210
211 case SYMBOL:
212 if( cookie == FOREFF )
213 return(reg);
214 break;
215
216 case LSH:
217 if( (isareg(reg)) && (p=constant(tp->t_right)) &&
218 !(unsign(tp->t_left->t_type)) &&
219 (p->t_value == 1 || p->t_value == 2) ) {
220 r = codegen(tp->t_left,FORREG,reg);
221 outmovr(r,reg,tp->t_left);
222 if( p->t_value == 2 )
223 outaddr(reg,reg,tp);
224 outaddr(reg,reg,tp);
225 fixresult(tp,cookie,reg);
226 return(reg);
227 }
228 break;
229
230 case EQMULT:
231 case EQDIV:
232 case LEQMULT:
233 case LEQDIV:
234 case EQMOD:
235 case LEQMOD:
236 case EQRSH:
1File: CODEGEN.C Page 5
237 case EQLSH:
238 case EQAND:
239 case EQOR:
240 case EQXOR:
241 if( indexreg(tp->t_left) ) {
242 reg = dreg(reg);
243 outmovr(r=tp->t_left->t_reg,reg,tp);
244 tp->t_left->t_reg = reg;
245 codegen(tp,cookie,reg+1);
246 outmovr(reg,r,tp);
247 return(reg);
248 }
249 break;
250
251 case ADD:
252 case EQADD:
253 if( (p=constant(tp->t_right)) && p->t_value < 0 &&
254 p->t_value >= -QUICKVAL ) {
255 p->t_value = - p->t_value;
256 tp->t_op =+ (SUB-ADD);
257 }
258 break;
259 }
260 sucomp(tp,reg,1);
261 if( (r=loadexpr(tp,cookie,reg)) >= 0 )
262 return(r);
263 if( (r=cqmark(tp,cookie,reg)) >= 0 )
264 return(r);
265 if( (r=hardrel(tp,cookie,reg)) >= 0 )
266 return(r);
267 if( cookie == FORCC && (p=match(tp,FOREFF,reg)) != 0 ) {
268 r = expand(tp,FOREFF,reg,p);
269 if( asgop(tp->t_op) && indexreg(tp->t_left) )
270 outcmp0(tp->t_left->t_reg,tp->t_left);
271 }
272 else if( p = match(tp,cookie,reg) )
273 r = expand(tp,cookie,reg,p);
274 else if( cookie != FORREG )
275 r = fixresult(tp,cookie,ucodegen(tp,FORREG,reg));
276 else
277 error("no code table for %d",tp->t_op);
278 return(r);
279 }
280
281 /* outstrcpy - output structure copy */
282 outstrcpy(lr,rr,size) /*[vlh]*/
283 int lr, rr; /* left register, right register */
284 int size; /* structure size to copy */
285 {
286 register int lab;
287 lab = nextlabel++;
288 printf("move #%d,r%d\n",(size/2)-1,dreg(lr));
289 outlab(lab);
290 printf("move (r%d)+,(r%d)+\ndbra r%d,L%d\n",rr,lr,dreg(lr),lab);
291 }
292
293 /* loadexpr - load an addressable expression into a register*/
294 /* This checks for any possible usage of the register indexed*/
295 /* addressing mode. Note that this relies on the good graces of the*/
1File: CODEGEN.C Page 6
296 /* load code skeletons not to muck up the compiler registers before*/
297 /* loading an addressable expression...*/
298 loadexpr(tp,cookie,reg) /* returns register loaded or -1*/
299 struct tnode *tp; /* pointer to expression tree*/
300 int reg; /* register to load*/
301 {
302 register struct tnode *rtp, *ltp, *xtp, *atp;
303 register int off, r, type, nr, ar, xr, xt;
304
305 if( tp->t_op == INDR || LOADABLE(tp) ) {
306 type = tp->t_type;
307 if( tp->t_op == INDR && (ltp=tp->t_left)->t_op == ADD ) {
308 rtp = ltp->t_right;
309 ltp = ltp->t_left;
310 off = 0;
311 if( rtp->t_op == CINT && ((off=rtp->t_value) < -128 ||
312 off > 127 || ltp->t_op != ADD ) ) {
313 tp = snalloc(type,AUTO,off,0,0);
314 if( indexreg(ltp) )
315 tp->t_reg = ltp->t_reg;
316 else {
317 r = codegen(ltp,FORREG,areg(reg));
318 if( isdreg(r) )
319 outmovr(r,areg(r),ltp);
320 tp->t_reg = areg(r);
321 }
322 }
323 else {
324 if( rtp->t_op == CINT ) {
325 rtp = ltp->t_right;
326 ltp = ltp->t_left;
327 }
328 if(indexreg(rtp) || (!(indexreg(ltp)) && (isreg(rtp)))) {
329 xtp = ltp;
330 ltp = rtp;
331 rtp = xtp;
332 }
333 xtp = atp = 0;
334 if( indexreg(ltp) ) {
335 ar = ltp->t_reg;
336 if( (isreg(rtp)) && rtp->t_type != CHAR ) {
337 xr = rtp->t_reg;
338 xt = rtp->t_type;
339 }
340 else
341 xtp = rtp;
342 }
343 else if( (isreg(ltp)) && ltp->t_type != CHAR &&
344 (lflag || rtp->t_op != ADDR) ) {
345 xr = ltp->t_reg;
346 xt = ltp->t_type;
347 atp = rtp;
348 }
349 else if( rtp->t_op == ADDR ) {
350 atp = ltp;
351 xtp = rtp;
352 }
353 else {
354 atp = rtp;
1File: CODEGEN.C Page 7
355 xtp = ltp;
356 }
357 nr = 0;
358 if( atp )
359 nr++;
360 if( xtp && (xtp->t_op != ADDR || lflag ) )
361 nr++;
362 if( dreg(nr+reg) <= HICREG ) {
363 r = reg;
364 if( atp ) {
365 ar = codegen(atp,FORREG,areg(r));
366 if( isdreg(ar) ) {
367 outmovr(ar,areg(ar),atp);
368 ar = areg(ar);
369 }
370 r++;
371 }
372 if( xtp && xtp->t_op == ADDR && !lflag ) {
373 tp = xtp->t_left;
374 tp->t_sc =+ (EXTOFF-EXTERNAL);
375 tp->t_offset =+ off;
376 tp->t_reg = ar;
377 }
378 else {
379 if( xtp ) {
380 xr = codegen(xtp,FORREG,areg(r));
381 xt = xtp->t_type;
382 }
383 tp = xnalloc(type,ar,off,xr,xt);
384 }
385 }
386 }
387 }
388 if( (isareg(reg)) && tp->t_type == CHAR )
389 reg = dreg(reg);
390 tp = tnalloc(LOAD,tp->t_type,SU_EASY,0,tp,null);
391 return( codegen(tp,cookie,reg) );
392 }
393 return(-1);
394
395 }
396
397 /* coffset - check offset for addressable node*/
398 char *coffset(tp) /* returns ptr to const off node*/
399 struct tnode *tp; /* pointer to node*/
400 {
401 register struct tnode *rtp;
402
403 if( tp->t_op == ADD ) {
404 rtp = tp->t_right;
405 if( rtp->t_op == CINT )
406 return(rtp);
407 if(!lflag) {
408 if( rtp->t_op == ADDR )
409 return(rtp->t_left);
410 rtp = tp->t_left;
411 if( rtp->t_op == ADDR ) {
412 tp->t_left = tp->t_right;
413 tp->t_right = rtp;
1File: CODEGEN.C Page 8
414 return(rtp->t_left);
415 }
416 }
417 }
418 return(0);
419 }
420
421 /* hardrel - do relationals returning a value*/
422 hardrel(tp,cookie,reg) /* returns reg or -1*/
423 struct tnode *tp; /* pointer to tree*/
424 int cookie; /* cookie for code generation*/
425 int reg; /* low register*/
426 {
427 char *p;
428 int op, lab1, lab2;
429
430 if( cookie != FORCC && (relop(op=tp->t_op) || op == LOR ||
431 op == LAND || op == NOT) ) {
432 lab1 = nextlabel++;
433 condbr(tp,TRUE,lab1,reg);
434 p = canon(cnalloc(INT,0));
435 codegen(p,cookie,reg);
436 lab2 = nextlabel++;
437 outgoto(lab2);
438 outlab(lab1);
439 p = canon(cnalloc(INT,1));
440 codegen(p,cookie,reg);
441 outlab(lab2);
442 return(reg);
443 }
444 return(-1);
445 }
446
447 /* cqmark - compile question mark operator*/
448 /* This does the compilation of the question mark operator.*/
449 cqmark(tp,cookie,reg) /* returns reg or -1*/
450 struct tnode *tp;
451 int cookie;
452 int reg;
453 {
454 register int lab1, lab2, savestk, r;
455
456 if( tp->t_op == QMARK && cookie != FORCC ) {
457 lab1 = nextlabel++;
458 condbr(tp->t_left,FALSE,lab1,reg);
459 savestk = stacksize;
460 r = scodegen(tp->t_right->t_left,cookie,reg); /* [mc] 4.0 */
461 outmovr(r,reg,tp);
462 stacksize = savestk;
463 outgoto(lab2=nextlabel++);
464 outlab(lab1);
465 r = scodegen(tp->t_right->t_right,cookie,reg); /* [mc] 4.0 */
466 outmovr(r,reg,tp);
467 outlab(lab2);
468 return(reg);
469 }
470 return(-1);
471 }
472
1File: CODEGEN.C Page 9
473 /* condbr - handle conditional branch code generation*/
474 /* This handles the conditional branch code generation, handling*/
475 /* the special cases for constants, ||, &&, ! and generating the*/
476 /* correct conditional branch instruction.*/
477 condbr(tp,dir,lab,reg)
478 struct tnode *tp;
479 int dir;
480 int lab;
481 int reg;
482 {
483 register struct tnode *ltp, *rtp;
484 register int lab1, optype, op, subdir;
485
486 ltp = tp->t_left;
487 if( binop(op=tp->t_op) )
488 rtp = tp->t_right;
489 subdir = dir; /*set up for LOR*/
490 switch( op ) {
491
492 case CINT:
493 if( !tp->t_value ) {
494 if( dir == FALSE )
495 outgoto(lab);
496 }
497 else if( dir != FALSE )
498 outgoto(lab);
499 break;
500
501 case NOT:
502 condbr(ltp,!dir,lab,reg);
503 break;
504
505 case LAND:
506 dir = !dir;
507 case LOR:
508 if( dir == FALSE ) {
509 lab1 = nextlabel++;
510 condbr(ltp,!subdir,lab1,reg);
511 condbr(rtp,subdir,lab,reg);
512 outlab(lab1);
513 }
514 else {
515 condbr(ltp,subdir,lab,reg);
516 condbr(rtp,subdir,lab,reg);
517 }
518 break;
519
520 case COMMA:
521 scodegen(tp->t_left,FOREFF,reg);
522 condbr(tp->t_right,dir,lab,reg);
523 break;
524
525 default:
526 if( op == NEQUALS && ltp->t_op == PREDEC &&
527 isdreg(ltp->t_left->t_reg) && ltp->t_left->t_type == INT &&
528 rtp->t_op == CINT && rtp->t_value == -1 ) {
529 outdbra(ltp->t_left->t_reg,lab);
530 break;
531 }
1File: CODEGEN.C Page 10
532 if( relop(op) && ltp->t_op == AUTOINC && rtp->t_op == AUTOINC &&
533 ltp->t_type == rtp->t_type )
534 outcmpm(tp);
535 else
536 scodegen(tp,FORCC,reg);
537 optype = 0;
538 if( relop(op) ) {
539 if( unorptr(ltp->t_type) || unorptr(rtp->t_type) )
540 optype =+ 1;
541 }
542 else
543 op = NEQUALS;
544 if(!dir)
545 op = invrel[op-EQUALS];
546 optype = brtab[op-EQUALS][optype];
547 printf("%s L%d\n",mnemonics[optype],lab);
548 break;
549 }
550 }
551
552 rcodegen(tpp,cookie,reg) /* returns changed flag*/
553 struct tnode **tpp; /* pointer to tree*/
554 int cookie; /* code generation cookie*/
555 int reg; /* register to use for code*/
556 {
557 register int change, op;
558 register struct tnode *tp;
559
560 tp = *tpp;
561 op = tp->t_op;
562 change = 0;
563 if( notleafop(op) && op != COMMA ) {
564 change =+ rcodegen(&tp->t_left,cookie,reg);
565 if( binop(op) )
566 change =+ rcodegen(&tp->t_right,cookie,reg);
567 change =+ rcgen(tpp,cookie,reg);
568 }
569 if( change )
570 *tpp = canon(*tpp);
571 return(change);
572 }
573
574 rcgen(tpp,cookie,reg) /* returns changed flag*/
575 struct tnode **tpp; /* pointer to tree*/
576 int cookie; /* code generation goals*/
577 int reg; /* register to use*/
578 {
579 register struct tnode *tp, *p, *ltp, *rtp;
580 register int op, change;
581
582 change = 0;
583 for( tp = *tpp ; binop(op=tp->t_op); *tpp=tp=canon(tp), change++ ) {
584 ltp = tp->t_left;
585 if( ltp->t_op != SYMBOL )
586 break;
587 rtp = tp->t_right;
588 switch( op ) {
589
590 case ASSIGN:
1File: CODEGEN.C Page 11
591 if( ltp->t_sc != REGISTER )
592 return(change);
593 switch( rtp->t_op ) {
594
595 case MULT:
596 case DIV:
597 case MOD:
598 case AND:
599 case OR:
600 case XOR:
601 case LSH:
602 case RSH:
603 if( isareg(ltp->t_reg) )
604 return(change);
605 case ADD:
606 case SUB:
607 p = rtp->t_right;
608 if(NOTADDRESSABLE(ltp) || !noref(rtp->t_right,ltp->t_reg))
609 return(change);
610 p = rtp->t_left;
611 if( p->t_op != SYMBOL || p->t_sc != REGISTER ||
612 p->t_reg != ltp->t_reg ) {
613 tp->t_right = p;
614 #ifndef NODEBUG
615 if( cflag > 1 )
616 putexpr("rcgen",tp);
617 #endif
618 codegen(tp,FOREFF,reg);
619 }
620 tp->t_right = rtp->t_right;
621 tp->t_op = rtp->t_op + (EQADD-ADD);
622 continue;
623 }
624 case EQLSH:
625 case EQRSH:
626 if( ltp->t_sc != REGISTER )
627 return(change);
628 case EQADD:
629 case EQSUB:
630 case EQAND:
631 case EQOR:
632 case EQXOR:
633 if( ltp->t_type == CHAR )
634 return(change);
635 #ifndef NODEBUG
636 if( cflag > 1 )
637 putexpr("rcgen",tp);
638 #endif
639 ucodegen(tp,FOREFF,reg);
640 tp = ltp;
641 continue;
642
643 case PREDEC:
644 case PREINC:
645 if( cookie == FORCC || ltp->t_type == CHAR )
646 return(change);
647 ucodegen(tp,FOREFF,reg);
648 tp = ltp;
649 continue;
1File: CODEGEN.C Page 12
650 }
651 break;
652 }
653 return(change);
654 }
655
656 noref(tp,reg) /* 4.0 change */
657 struct tnode *tp; /* returns 1 if no reference in tree to reg */
658 int reg;
659 {
660 if ( leafop(tp->t_op) ) {
661 if (tp->t_op == SYMBOL && tp->t_sc == REGISTER && tp->t_reg == reg)
662 return(0);
663 return(1);
664 }
665 if ( !noref(tp->t_left,reg) )
666 return(0);
667 if (binop(tp->t_op))
668 return( noref(tp->t_right,reg) );
669 return(1);
670 }
671
672 /* cdsize - compute size of data item*/
673 cdsize(tp) /* returns data size in bytes*/
674 struct tnode *tp;
675 {
676 register int type;
677
678 type = tp->t_type;
679 if( suptype(type) )
680 return(PTRSIZE);
681 switch( type ) {
682
683 case CHAR:
684 case INT:
685 case UNSIGNED:
686 return(INTSIZE);
687
688 case LONG:
689 case FLOAT: /* [vlh] 3.4 */
690 return(LONGSIZE);
691 }
692 error("cdsize: invalid type %d",type);
693 return(0);
694 }
695
696 dofarg(tp) /* returns number of bytes pushed*/
697 struct tnode *tp; /* pointer to expression tree*/
698 {
699 register int nb;
700
701 nb = 0;
702 if( tp->t_op == SYMBOL && tp->t_sc == STRUCT )
703 error("structure operation not implemented");
704 else if( stacksize ) {
705 codegen(tp,FORSTACK,0);
706 nb = cdsize(tp);
707 }
708 else
1File: CODEGEN.C Page 13
709 codegen(tp,FORSP,0);
710 return( nb );
711 }
712
713 /* dobitadd - do bit operation address checking and fixup*/
714 dobitadd(tp,bitno) /* returns -1 if can't or bitno*/
715 struct tnode *tp;
716 int bitno;
717 {
718 register int offset;
719
720 if( tp->t_type == CHAR )
721 offset = 0;
722 else
723 offset = cdsize(tp) - (bitno/BITSPBYTE) - 1;
724 if( tp->t_op == SYMBOL ) {
725 switch( tp->t_sc ) {
726
727 case REGISTER:
728 if( isdreg(tp->t_reg) )
729 return(bitno);
730 default:
731 return(-1);
732
733 case EXTERNAL:
734 case STATIC:
735 case REGOFF:
736 case STATOFF:
737 case EXTOFF:
738 tp->t_offset =+ offset;
739 return( bitno % BITSPBYTE );
740 }
741 }
742 else if( tp->t_op == INDR ) {
743 tp->t_left = tnalloc(ADD,tp->t_left->t_type,0,0,tp->t_left,
744 cnalloc(INT,offset));
745 return( bitno % BITSPBYTE );
746 }
747 return(-1);
748 }
749
750 isonebit(tp) /* returns -1 if not 1 bit, else bitno*/
751 struct tnode *tp; /* pointer to tree*/
752 {
753 if( tp = constant(tp) )
754 return( onebit(tp->t_value) );
755 return(-1);
756 }

View File

@@ -0,0 +1,92 @@
/*
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
#define OPCALL 167
#define POP4 169
#define LADDRP 168
/*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;
};

View File

@@ -0,0 +1,94 @@
1File: CSKEL.H Page 1
1 /*
2 Copyright 1981
3 Alcyon Corporation
4 8474 Commerce Av.
5 San Diego, Ca. 92121
6 */
7
8 /*built-in literals*/
9 #define MOV 128
10 #define MOVL 129
11 #define JSR 130
12 #define CLR 131
13 #define CLRL 132
14 #define EXTW 133
15 #define EXTL 134
16 #define LEA 135
17 #define STK 136
18
19 /*built-in macros*/
20 #define TREE 141
21 #define LEFT 142
22 #define RIGHT 143
23 #define LOFFSET 144
24 #define ROFFSET 145
25 #define LADDR 146
26 #define RADDR 147
27 #define CR 148
28 #define NR 149
29 #define CAR 150
30 #define NAR 151
31 #define TLEFT 152
32 #define TRIGHT 153
33 #define TEITHER 154
34 #define TLEFTL 155
35 #define OP 156
36 #define AOP 157
37 #define MODSWAP 158
38 #define EXL 159
39 #define EXLR 160
40 #define EXLRN 161
41 #define EXRL 162
42 #define EXRLN 163
43 #define PSH 164
44 #define POP 165
45 #define POP8 166
46 #define OPCALL 167
47 #define POP4 169
48 #define LADDRP 168
49
50 /*modifiers for compiling sub-trees*/
51 #define S_INDR 1 /*indirection*/
52 #define S_STACK 2 /*onto stack*/
53 #define S_FORCC 4 /*set condition codes*/
54 #define S_NEXT 8 /*into next register*/
55
56 /*Sethy-Ullman values*/
57 #define SU_ZERO 0x000 /*zero*/
58 #define SU_ONE 0x100 /*one*/
59 #define SU_SMALL 0x200 /*constant between 1 and 8*/
1File: CSKEL.H Page 2
60 #define SU_QUICK 0x300 /*quick constant between -128 and 127*/
61 #define SU_CONST 0x400 /*any constant*/
62 #define SU_AREG 0x500 /*A register*/
63 #define SU_REG 0x600 /*register*/
64 #define SU_ADDR 0x700 /*addressable*/
65 #define SU_XREG 0x800 /*A register used as data...*/
66 #define SU_EASY 0x900 /*easy*/
67 #define SU_HARD 0xa00 /*hard*/
68 #define SU_VHARD 0xb00 /*very hard ... function calls, etc.*/
69 #define SU_ANY 0xf00 /*anything*/
70 #define ADDRESSABLE(x) (x->t_su<=SU_ADDR)
71 #define NOTADDRESSABLE(x) (x->t_su>SU_ADDR)
72 #define LOADABLE(x) (x->t_su<=SU_XREG)
73
74 /*flag byte (operand type):*/
75 #define T_CHAR 1 /*char only*/
76 #define T_SHORT 2 /*short*/
77 #define T_INT 3 /*int only*/
78 #define T_LONG 4 /*long*/
79 #define T_UCHAR 5 /*unsigned char*/
80 #define T_USHORT 6 /*unsigned short*/
81 #define T_UNSN 7 /*unsigned int*/
82 #define T_ULONG 8 /*unsigned long*/
83 #define T_FLOAT 9 /*float*/
84 #define T_DOUB 10 /*double*/
85 #define T_ANY 11 /*int or word (implied)*/
86 #define T_INDR 0x10 /*pointer type (bit)*/
87
88 struct skeleton {
89 int sk_left;
90 int sk_right;
91 char *sk_def;
92 };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
$ assign drb0:[steve.cpm68k.v103.cgen] new:
$ set noon
$ dif :== diff/ign=(comm,blan,spac,trail,form)/comm=slash
$ dif CANON.C new:CANON.C
$ dif CGEN.H new:CGEN.H
$ dif CODEGEN.C new:CODEGEN.C
$ dif CSKEL.H new:CSKEL.H
$ dif CSKELS.C new:CSKELS.C
$ dif ICODE.H new:ICODE.H
$ dif INIT.C new:INIT.C
$ dif INTERF.C new:INTERF.C
$ dif MACHINE.11 new:MACHINE.11
$ dif MACHINE.68K new:MACHINE.68K
$ dif MACHINE.H new:MACHINE.H
$ dif MACHINE.VAX new:MACHINE.VAX
$ dif MAIN.C new:MAIN.C
$ dif OPTAB.C new:OPTAB.C
$ dif PUTEXPR.C new:PUTEXPR.C
$ dif SMATCH.C new:SMATCH.C
$ dif SUCOMP.C new:SUCOMP.C
$ dif TABL.C new:TABL.C
$ dif UTIL.C new:UTIL.C
$ dif VERSION.C new:VERSION.C

View File

@@ -0,0 +1,22 @@
$ set noon
$ dif :== diff/ign=(comm,blan,spac,trail,form)/comm=slash
$ dif CANON.C new:CANON.C
$ dif CGEN.H new:CGEN.H
$ dif CODEGEN.C new:CODEGEN.C
$ dif CSKEL.H new:CSKEL.H
$ dif CSKELS.C new:CSKELS.C
$ dif ICODE.H new:ICODE.H
$ dif INIT.C new:INIT.C
$ dif INTERF.C new:INTERF.C
$ dif MACHINE.11 new:MACHINE.11
$ dif MACHINE.68K new:MACHINE.68K
$ dif MACHINE.H new:MACHINE.H
$ dif MACHINE.VAX new:MACHINE.VAX
$ dif MAIN.C new:MAIN.C
$ dif OPTAB.C new:OPTAB.C
$ dif PUTEXPR.C new:PUTEXPR.C
$ dif SMATCH.C new:SMATCH.C
$ dif SUCOMP.C new:SUCOMP.C
$ dif TABL.C new:TABL.C
$ dif UTIL.C new:UTIL.C
$ dif VERSION.C new:VERSION.C

View File

@@ -0,0 +1,251 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "machine.h"
/*
* 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 EQNOT 47
#define EQNEG 48
#define DOCAST 49
#define STASSIGN 50 /*[vlh]*/
#define LONG2F 51 /*[vlh] 3.4*/
#define FLOAT2L 52 /*[vlh] 3.4*/
#define INT2F 53 /*[vlh] 3.4*/
#define FLOAT2I 54 /*[vlh] 3.4*/
#define LCGENOP 55 /*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
#define CFLOAT 79 /*[vlh] 3.4*/
/*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 FRETURN 94
#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 DREG0 0
#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
#define CFINDR 11 /* [vlh] 3.4 */
/*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 /* chars per symbol */
#define TRUE 1
#define FALSE 0
#define TABC '\t' /* tab character */
#define EOLC '\n' /* end of line character */
#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];
};
#ifdef PDP11
struct { short hiword; short loword; };
#endif
#ifdef MC68000
struct { short hiword; short loword; };
#endif
#ifdef VAX
struct { short loword; short hiword; };
#endif
#define EXPSIZE 1024
int exprarea[EXPSIZE];
/* v6io buffer declaration */
#define BLEN 512
struct iobuf{
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};

View File

@@ -0,0 +1,256 @@
1File: ICODE.H Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7 #include "machine.h"
8 /*
9 * intermediate code operators
10 * 0=>EOF, special operator
11 */
12 #define EOF 0
13
14 /*1-59=>operators that generate code (entries in code gen optab)*/
15 #define ADD 1
16 #define SUB 2
17 #define MULT 3
18 #define DIV 4
19 #define MOD 5
20 #define RSH 6
21 #define LSH 7
22 #define AND 8
23 #define OR 9
24 #define XOR 10
25 #define NOT 11
26 #define UMINUS 12
27 #define COMPL 13
28 #define PREDEC 14
29 #define PREINC 15
30 #define POSTDEC 16
31 #define POSTINC 17
32 #define ASSIGN 18
33 #define EQADD 19
34 #define EQSUB 20
35 #define EQMULT 21
36 #define EQDIV 22
37 #define EQMOD 23
38 #define EQRSH 24
39 #define EQLSH 25
40 #define EQAND 26
41 #define EQOR 27
42 #define EQXOR 28
43 #define FJSR 29
44 #define EQUALS 30
45 #define NEQUALS 31
46 #define GREAT 32
47 #define GREATEQ 33
48 #define LESS 34
49 #define LESSEQ 35
50 #define INT2L 36
51 #define LONG2I 37
52
53 /*machine dependent operators that generate code*/
54 #define BTST 38
55 #define LOAD 39
56 #define LMULT 40
57 #define LDIV 41
58 #define LMOD 42
59 #define LEQMULT 43
1File: ICODE.H Page 2
60 #define LEQDIV 44
61 #define LEQMOD 45
62 #define EQADDR 46
63 #define EQNOT 47
64 #define EQNEG 48
65 #define DOCAST 49
66
67 #define STASSIGN 50 /*[vlh]*/
68 #define LONG2F 51 /*[vlh] 3.4*/
69 #define FLOAT2L 52 /*[vlh] 3.4*/
70 #define INT2F 53 /*[vlh] 3.4*/
71 #define FLOAT2I 54 /*[vlh] 3.4*/
72 #define LCGENOP 55 /*change if adding more operators...*/
73
74 /*intermediate code operators that do not generate code*/
75 #define ADDR 60
76 #define INDR 61
77 #define LAND 62
78 #define LOR 63
79 #define QMARK 64
80 #define COLON 65
81 #define COMMA 66
82 #define CINT 67
83 #define CLONG 68
84 #define SYMBOL 69
85 #define AUTOINC 70
86 #define AUTODEC 71
87 #define CALL 72
88 #define NACALL 73
89 #define BFIELD 74
90 #define IFGOTO 75
91 #define INIT 76
92 #define CFORREG 77
93 #define DCLONG 78
94 #define CFLOAT 79 /*[vlh] 3.4*/
95
96 /*operators local to parser*/
97 #define CAST 80
98 #define SEMI 81
99 #define LCURBR 82
100 #define RCURBR 83
101 #define LBRACK 84
102 #define RBRACK 85
103 #define LPAREN 86
104 #define RPAREN 87
105 #define STRING 88
106 #define RESWORD 89
107 #define APTR 90
108 #define PERIOD 91
109 #define SIZEOF 92
110 #define MPARENS 93
111 #define FRETURN 94
112 #define STACKEND 100
113
114 /*data types*/
115 #define TYPELESS 0
116 #define CHAR 1
117 #define SHORT 2
118 #define INT 3
1File: ICODE.H Page 3
119 #define LONG 4
120 #define UCHAR 5
121 #define USHORT 6
122 #define UNSIGNED 7
123 #define ULONG 8
124 #define FLOAT 9
125 #define DOUBLE 10
126
127 /*data types local to parser*/
128 #define STRUCT 11
129 #define FRSTRUCT 12
130 #define LLABEL 13
131
132 /*type flags and definitions*/
133 #define TYPE 017
134 #define SUPTYP 060
135 #define ALLTYPE 077
136 #define POINTER 020
137 #define FUNCTION 040
138 #define ARRAY 060
139 #define SUTYPLEN 2
140
141 /*data registers*/
142 #define DREG0 0
143 #define DREG2 2
144 #define DREG3 3
145 #define DREG4 4
146 #define DREG5 5
147 #define DREG6 6
148 #define DREG7 7
149 #define AREG3 11
150 #define AREG4 12
151 #define AREG5 13
152
153 /*storage classes*/
154 #define AUTO 1
155 #define REGISTER 2
156 #define EXTERNAL 3
157 #define STATIC 4
158 #define REGOFF 5
159 #define EXTOFF 6
160 #define STATOFF 7
161 #define INDEXED 8
162
163 /*exclusively code generator storage classes*/
164 #define CINDR 9
165 #define CLINDR 10
166 #define CFINDR 11 /* [vlh] 3.4 */
167
168 /*exclusively parser storage classes*/
169 #define STRPROTO 9
170 #define PDECLIST 10
171 #define PARMLIST 11
172 #define BFIELDCL 12
173 #define UNELCL 13
174 #define STELCL 14
175
176
177 /*opinfo table bits*/
1File: ICODE.H Page 4
178 #define OPPRI 077
179 #define OPBIN 0100
180 #define OPLVAL 0200
181 #define OPREL 0400
182 #define OPASSIGN 01000
183 #define OPLWORD 02000
184 #define OPRWORD 04000
185 #define OPCOM 010000
186 #define OPRAS 020000
187 #define OPTERM 040000
188 #define OPCONVS 0100000
189
190 /*68000 definitions*/
191 #define PTRSIZE 4
192 #define INTSIZE 2
193 #define LONGSIZE 4
194 #define SSIZE 8 /* chars per symbol */
195 #define TRUE 1
196 #define FALSE 0
197 #define TABC '\t' /* tab character */
198 #define EOLC '\n' /* end of line character */
199 #define BITSPBYTE 8
200
201 /*operator class priorities*/
202 #define TRMPRI 0 /* terminal nodes */
203 #define RPNPRI 1 /* ) and ] */
204 #define CALPRI 2 /* in-stack call, ( or [ */
205 #define COLPRI 3 /* init or case priority for : or , */
206 #define STKPRI 4 /* priority of end of stack */
207 #define COMPRI 5 /* normal priority for , */
208 #define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
209 #define QMKPRI 7 /* ?: */
210 #define LORPRI 8 /* || */
211 #define LNDPRI 9 /* && */
212 #define ORPRI 10 /* |, ! */
213 #define ANDPRI 11 /* & */
214 #define EQLPRI 12 /* ==, != */
215 #define RELPRI 13 /* >, <, >=, <= */
216 #define SHFPRI 14 /* <<, >> */
217 #define ADDPRI 15 /* +, - */
218 #define MULPRI 16 /* *, /, % */
219 #define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
220 #define LPNPRI 18 /* ., ->, [, (, function call */
221 #define PSTPRI 19 /* in-stack post--, post++ */
222
223 struct io_buf {
224 int io_fd;
225 int io_nc;
226 char *io_p;
227 char io_b[512];
228 };
229
230 #ifdef PDP11
231 struct { short hiword; short loword; };
232 #endif
233 #ifdef MC68000
234 struct { short hiword; short loword; };
235 #endif
236 #ifdef VAX
1File: ICODE.H Page 5
237 struct { short loword; short hiword; };
238 #endif
239
240 #define EXPSIZE 1024
241 int exprarea[EXPSIZE];
242
243 /* v6io buffer declaration */
244 #define BLEN 512
245
246 struct iobuf{
247 int fildes;
248 int nunused;
249 char *xfree;
250 char buff[BLEN];
251 };

View File

@@ -0,0 +1,418 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char null[]=0;
#define SSIZE 8 /* chars per symbol */
/*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;
int lineno=0;
int naregs=0;
int ndregs=0;
int errcnt=0;
int stacksize=0;
char *tnalloc();
char *snalloc();
char *cenalloc();
char *xnalloc();
char *talloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
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 isfloat(type) (type==FLOAT)
#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 NOTLOFFSET 0
/* one line routines turned into defines [vlh] for speed */
/*outgoto - output "bra L[labno]"*/
#define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
/*outlab - output "L[labno]:"*/
#define outlab(lab) if (lab>0) printf("L%d:",lab)
/*outext - output register sign extension*/
#define outext(reg) printf("ext.l R%d\n",reg)
/*outuext - output unsigned to long register extension*/
#define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
/*outswap - output swap register instruction*/
#define outswap(reg) printf("swap R%d\n",reg)
/*outaddr - output "add [type] R1 R2" instruction*/
#define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
/*outccsave - ouput instruction to move cc's to register*/
#define outccsave(reg) printf("move sr,R%d\n",reg)
/*outccrestore - output instruction to restore cc's from register*/
#define outccrestore(reg) printf("move R%d,ccr\n",reg)
/*basetype - get the btype info sans unsigned*/
#define basetype(type) ((type==UNSIGNED) ? INT : type)
#define unsign(type) ((type) == UNSIGNED)
#define longorptr(type) (type==LONG || (type&SUPTYP))
#define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
#define dreg(reg) ((reg) & (~AREGLO))
#define areg(reg) ((reg) | AREGLO)
#define isareg(reg) ((reg) >= AREGLO)
#define isdreg(reg) ((reg) < AREGLO)
#define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)
/*
* 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 EQNOT 47
#define EQNEG 48
#define DOCAST 49
#define STASSIGN 50 /*[vlh]*/
#define LONG2F 51 /*[vlh] 3.4*/
#define FLOAT2L 52 /*[vlh] 3.4*/
#define INT2F 53 /*[vlh] 3.4*/
#define FLOAT2I 54 /*[vlh] 3.4*/
#define LCGENOP 55 /*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
#define CFLOAT 79 /*[vlh] 3.4*/
/*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 FRETURN 94
#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 DREG0 0
#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
#define CFINDR 11 /* [vlh] 3.4 */
/*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 TRUE 1
#define FALSE 0
#define TABC '\t' /* tab character */
#define EOLC '\n' /* end of line character */
#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;
/* v6io buffer declaration */
#define BLEN 512
struct iobuf {
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};
struct io_buf ibuf={0}, obuf={0};
int bol=0;
int errflg=0;
int level=0;
int onepass=0;
char *opap=0;

View File

@@ -0,0 +1,426 @@
1File: INIT.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8
9 char null[]=0;
10 #define SSIZE 8 /* chars per symbol */
11
12 /*operator tree node for unary and binary operators*/
13 struct tnode {
14 int t_op; /*operator*/
15 int t_type; /*data type of result*/
16 int t_su; /*Sethy-Ullman number*/
17 int t_ssp;
18 struct tnode *t_left; /*left sub-tree*/
19 struct tnode *t_right; /*right sub-tree (undefined if unary)*/
20 };
21
22 /*constant terminal node*/
23 struct conode {
24 int t_op; /*operator*/
25 int t_type; /*type*/
26 int t_su; /*Sethy-Ullman number*/
27 int t_ssp;
28 int t_value; /*value or label number*/
29 };
30
31 struct lconode {
32 int t_op; /*operator*/
33 int t_type; /*type*/
34 int t_su; /*Sethy-Ullman number*/
35 int t_ssp;
36 long t_lvalue; /*value or label number*/
37 };
38
39 /*local symbol terminal node*/
40 struct symnode {
41 int t_op; /*operator*/
42 int t_type; /*symbol data type*/
43 int t_su; /*Sethy-Ullman number*/
44 int t_ssp;
45 int t_sc; /*storage class*/
46 int t_offset; /*register offset*/
47 int t_reg; /*register number*/
48 int t_label; /*label number if static*/
49 };
50
51 /*external symbol reference node*/
52 struct extnode {
53 int t_op; /*operator*/
54 int t_type; /*symbol data type*/
55 int t_su; /*Sethy-Ullman number*/
56 int t_ssp;
57 int t_sc; /*storage class*/
58 int t_offset; /*register offset*/
59 int t_reg; /*register number*/
1File: INIT.C Page 2
60 char t_symbol[SSIZE]; /*symbol name*/
61 };
62
63 /*68000 special - indexed symbol node*/
64 /*this is used to generate a An(off,Xn.type) address*/
65 struct indexnode {
66 int t_op;
67 int t_type;
68 int t_su;
69 int t_ssp;
70 int t_sc;
71 int t_offset;
72 int t_reg;
73 int t_xreg;
74 int t_xtype;
75 };
76
77 int lflag=0;
78 int dflag=0;
79 int mflag=0;
80 int cflag=0;
81 int eflag=0;
82 int fflag=0;
83 int oflag=0;
84 int lineno=0;
85 int naregs=0;
86 int ndregs=0;
87 int errcnt=0;
88 int stacksize=0;
89
90 char *tnalloc();
91 char *snalloc();
92 char *cenalloc();
93 char *xnalloc();
94 char *talloc();
95 char *cnalloc();
96 char *lcnalloc();
97 char *fpcnalloc();
98 char *canon();
99 char *commute();
100 char *constant();
101 char *match();
102 char *addptree();
103 char *fixbfield();
104 char *coffset();
105 char *tcopy();
106
107 #define wallign(add) ((add+1)&(~1))
108 #define array(type) ((type&SUPTYP)==ARRAY)
109 #define function(type) ((type&SUPTYP)==FUNCTION)
110 #define pointer(type) ((type&SUPTYP)==POINTER)
111 #define notarray(type) ((type&SUPTYP)!=ARRAY)
112 #define notfunction(type) ((type&SUPTYP)!=FUNCTION)
113 #define notpointer(type) ((type&SUPTYP)!=POINTER)
114 #define isfloat(type) (type==FLOAT)
115 #define btype(type) (type&TYPE)
116 #define suptype(type) (type&SUPTYP)
117 #define alltype(type) (type&(SUPTYP|TYPE))
118 #define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
1File: INIT.C Page 3
119 #define relop(op) ((opinfo[op]&OPREL)!=0)
120 #define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
121 #define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
122 #define rasop(op) ((opinfo[op]&OPRAS)!=0)
123 #define binop(op) ((opinfo[op]&OPBIN)!=0)
124 #define unaryop(op) ((opinfo[op]&(OPBIN|OPTERM))==0)
125 #define leafop(op) ((opinfo[op]&OPTERM)!=0)
126 #define notleafop(op) ((opinfo[op]&OPTERM)==0)
127 #define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
128 #define oppriority(op) (opinfo[op]&OPPRI)
129 #define commop(op) ((opinfo[op]&OPCOM)!=0)
130 #define convop(op) ((opinfo[op]&OPCONVS)!=0)
131 #define notconvop(op) ((opinfo[op]&OPCONVS)==0)
132 #define max(a,b) (a>b?a:b)
133 #define min(a,b) (a<b?a:b)
134
135 #define QUICKVAL 8
136 #define LEP 14
137 #define FORCC 1
138 #define FOREFF 2
139 #define FORSTACK 3
140 #define FORCREG 4
141 #define FORSP 5
142 #define FORREG 4
143 #define HICREG 2
144 #define NCREGS 3
145 #define AREGLO 8
146 #define IMMED 1
147 #define NOTIMMED 0
148 #define NOTLOFFSET 0
149
150 /* one line routines turned into defines [vlh] for speed */
151
152 /*outgoto - output "bra L[labno]"*/
153 #define outgoto(lab) if (lab>0) printf("bra L%d\n",lab)
154 /*outlab - output "L[labno]:"*/
155 #define outlab(lab) if (lab>0) printf("L%d:",lab)
156
157 /*outext - output register sign extension*/
158 #define outext(reg) printf("ext.l R%d\n",reg)
159 /*outuext - output unsigned to long register extension*/
160 #define outuext(reg) printf("swap R%d\nclr R%d\nswap R%d\n",reg,reg,reg)
161 /*outswap - output swap register instruction*/
162 #define outswap(reg) printf("swap R%d\n",reg)
163 /*outaddr - output "add [type] R1 R2" instruction*/
164 #define outaddr(r1,r2,tp) outrr("add",r1,r2,(tp))
165 /*outccsave - ouput instruction to move cc's to register*/
166 #define outccsave(reg) printf("move sr,R%d\n",reg)
167 /*outccrestore - output instruction to restore cc's from register*/
168 #define outccrestore(reg) printf("move R%d,ccr\n",reg)
169 /*basetype - get the btype info sans unsigned*/
170 #define basetype(type) ((type==UNSIGNED) ? INT : type)
171 #define unsign(type) ((type) == UNSIGNED)
172 #define longorptr(type) (type==LONG || (type&SUPTYP))
173 #define unorptr(type) (type==UNSIGNED || (type&SUPTYP))
174 #define dreg(reg) ((reg) & (~AREGLO))
175 #define areg(reg) ((reg) | AREGLO)
176 #define isareg(reg) ((reg) >= AREGLO)
177 #define isdreg(reg) ((reg) < AREGLO)
1File: INIT.C Page 4
178 #define isreg(tp) ((tp)->t_op == SYMBOL && (tp)->t_sc == REGISTER)
179
180 /*
181 * intermediate code operators
182 * 0=>EOF, special operator
183 */
184 #define EOF 0
185
186 /*1-59=>operators that generate code (entries in code gen optab)*/
187 #define ADD 1
188 #define SUB 2
189 #define MULT 3
190 #define DIV 4
191 #define MOD 5
192 #define RSH 6
193 #define LSH 7
194 #define AND 8
195 #define OR 9
196 #define XOR 10
197 #define NOT 11
198 #define UMINUS 12
199 #define COMPL 13
200 #define PREDEC 14
201 #define PREINC 15
202 #define POSTDEC 16
203 #define POSTINC 17
204 #define ASSIGN 18
205 #define EQADD 19
206 #define EQSUB 20
207 #define EQMULT 21
208 #define EQDIV 22
209 #define EQMOD 23
210 #define EQRSH 24
211 #define EQLSH 25
212 #define EQAND 26
213 #define EQOR 27
214 #define EQXOR 28
215 #define FJSR 29
216 #define EQUALS 30
217 #define NEQUALS 31
218 #define GREAT 32
219 #define GREATEQ 33
220 #define LESS 34
221 #define LESSEQ 35
222 #define INT2L 36
223 #define LONG2I 37
224
225 /*machine dependent operators that generate code*/
226 #define BTST 38
227 #define LOAD 39
228 #define LMULT 40
229 #define LDIV 41
230 #define LMOD 42
231 #define LEQMULT 43
232 #define LEQDIV 44
233 #define LEQMOD 45
234 #define EQADDR 46
235 #define EQNOT 47
236 #define EQNEG 48
1File: INIT.C Page 5
237 #define DOCAST 49
238
239 #define STASSIGN 50 /*[vlh]*/
240 #define LONG2F 51 /*[vlh] 3.4*/
241 #define FLOAT2L 52 /*[vlh] 3.4*/
242 #define INT2F 53 /*[vlh] 3.4*/
243 #define FLOAT2I 54 /*[vlh] 3.4*/
244 #define LCGENOP 55 /*change if adding more operators...*/
245
246 /*intermediate code operators that do not generate code*/
247 #define ADDR 60
248 #define INDR 61
249 #define LAND 62
250 #define LOR 63
251 #define QMARK 64
252 #define COLON 65
253 #define COMMA 66
254 #define CINT 67
255 #define CLONG 68
256 #define SYMBOL 69
257 #define AUTOINC 70
258 #define AUTODEC 71
259 #define CALL 72
260 #define NACALL 73
261 #define BFIELD 74
262 #define IFGOTO 75
263 #define INIT 76
264 #define CFORREG 77
265 #define DCLONG 78
266 #define CFLOAT 79 /*[vlh] 3.4*/
267
268 /*operators local to parser*/
269 #define CAST 80
270 #define SEMI 81
271 #define LCURBR 82
272 #define RCURBR 83
273 #define LBRACK 84
274 #define RBRACK 85
275 #define LPAREN 86
276 #define RPAREN 87
277 #define STRING 88
278 #define RESWORD 89
279 #define APTR 90
280 #define PERIOD 91
281 #define SIZEOF 92
282 #define MPARENS 93
283 #define FRETURN 94
284 #define STACKEND 100
285
286 /*data types*/
287 #define TYPELESS 0
288 #define CHAR 1
289 #define SHORT 2
290 #define INT 3
291 #define LONG 4
292 #define UCHAR 5
293 #define USHORT 6
294 #define UNSIGNED 7
295 #define ULONG 8
1File: INIT.C Page 6
296 #define FLOAT 9
297 #define DOUBLE 10
298
299 /*data types local to parser*/
300 #define STRUCT 11
301 #define FRSTRUCT 12
302 #define LLABEL 13
303
304 /*type flags and definitions*/
305 #define TYPE 017
306 #define SUPTYP 060
307 #define ALLTYPE 077
308 #define POINTER 020
309 #define FUNCTION 040
310 #define ARRAY 060
311 #define SUTYPLEN 2
312
313 /*data registers*/
314 #define DREG0 0
315 #define DREG2 2
316 #define DREG3 3
317 #define DREG4 4
318 #define DREG5 5
319 #define DREG6 6
320 #define DREG7 7
321 #define AREG3 11
322 #define AREG4 12
323 #define AREG5 13
324
325 /*storage classes*/
326 #define AUTO 1
327 #define REGISTER 2
328 #define EXTERNAL 3
329 #define STATIC 4
330 #define REGOFF 5
331 #define EXTOFF 6
332 #define STATOFF 7
333 #define INDEXED 8
334
335 /*exclusively code generator storage classes*/
336 #define CINDR 9
337 #define CLINDR 10
338 #define CFINDR 11 /* [vlh] 3.4 */
339
340 /*exclusively parser storage classes*/
341 #define STRPROTO 9
342 #define PDECLIST 10
343 #define PARMLIST 11
344 #define BFIELDCL 12
345 #define UNELCL 13
346 #define STELCL 14
347
348
349 /*opinfo table bits*/
350 #define OPPRI 077
351 #define OPBIN 0100
352 #define OPLVAL 0200
353 #define OPREL 0400
354 #define OPASSIGN 01000
1File: INIT.C Page 7
355 #define OPLWORD 02000
356 #define OPRWORD 04000
357 #define OPCOM 010000
358 #define OPRAS 020000
359 #define OPTERM 040000
360 #define OPCONVS 0100000
361
362 /*68000 definitions*/
363 #define PTRSIZE 4
364 #define INTSIZE 2
365 #define LONGSIZE 4
366 #define TRUE 1
367 #define FALSE 0
368 #define TABC '\t' /* tab character */
369 #define EOLC '\n' /* end of line character */
370 #define BITSPBYTE 8
371
372 /*operator class priorities*/
373 #define TRMPRI 0 /* terminal nodes */
374 #define RPNPRI 1 /* ) and ] */
375 #define CALPRI 2 /* in-stack call, ( or [ */
376 #define COLPRI 3 /* init or case priority for : or , */
377 #define STKPRI 4 /* priority of end of stack */
378 #define COMPRI 5 /* normal priority for , */
379 #define ASGPRI 6 /* =, +=, -=, *=, /=, %=, ... */
380 #define QMKPRI 7 /* ?: */
381 #define LORPRI 8 /* || */
382 #define LNDPRI 9 /* && */
383 #define ORPRI 10 /* |, ! */
384 #define ANDPRI 11 /* & */
385 #define EQLPRI 12 /* ==, != */
386 #define RELPRI 13 /* >, <, >=, <= */
387 #define SHFPRI 14 /* <<, >> */
388 #define ADDPRI 15 /* +, - */
389 #define MULPRI 16 /* *, /, % */
390 #define UNOPRI 17 /* ++, --, &, *, -, ~, sizeof */
391 #define LPNPRI 18 /* ., ->, [, (, function call */
392 #define PSTPRI 19 /* in-stack post--, post++ */
393
394 struct io_buf {
395 int io_fd;
396 int io_nc;
397 char *io_p;
398 char io_b[512];
399 };
400 struct { int hiword; int loword; };
401 #define EXPSIZE 1024
402 int exprarea[EXPSIZE]=0;
403
404 /* v6io buffer declaration */
405 #define BLEN 512
406
407 struct iobuf {
408 int fildes;
409 int nunused;
410 char *xfree;
411 char buff[BLEN];
412 };
413 struct io_buf ibuf={0}, obuf={0};
1File: INIT.C Page 8
414 int bol=0;
415 int errflg=0;
416 int level=0;
417 int onepass=0;
418 char *opap=0;

View File

@@ -0,0 +1,134 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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);
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
if( dflag )
outline();
if( exprok(tp) )
condbr(canon(tp),dir,lab,0);
}
outcforreg(tp)
struct tnode *tp;
{
if( dflag )
outline();
if( exprok(tp) )
outmovr(scodegen(canon(tp),FORREG,0),0,tp);
}
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 != CINT )
printf(".dc.l ");
else {
printf(".dc");
outtype(typeout);
putchar(' ');
}
outaexpr(tp,NOTIMMED); /* [vlh] 4.0 not 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) )
return(0);
return( exprok(tp->t_left) );
}
outline()
{
if( onepass && !bol )
putchar('\n');
printf("*line %d\n",lineno);
}

View File

@@ -0,0 +1,137 @@
1File: INTERF.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9 int bol;
10 int onepass;
11
12 /* outexpr - output expression*/
13 outexpr(tp) /* returns - none*/
14 struct tnode *tp; /* pointer to tree node*/
15 {
16 if( dflag )
17 outline();
18 if( exprok(tp) )
19 scodegen(canon(tp),FOREFF,0);
20 }
21
22 outifgoto(tp,dir,lab)
23 struct tnode *tp;
24 int dir;
25 int lab;
26 {
27 if( dflag )
28 outline();
29 if( exprok(tp) )
30 condbr(canon(tp),dir,lab,0);
31 }
32
33 outcforreg(tp)
34 struct tnode *tp;
35 {
36 if( dflag )
37 outline();
38 if( exprok(tp) )
39 outmovr(scodegen(canon(tp),FORREG,0),0,tp);
40 }
41
42 outinit(tp) /* returns - none*/
43 struct tnode *tp;
44 {
45 register int typeout;
46
47 if( dflag )
48 outline();
49 if( exprok(tp) ) {
50 typeout = tp->t_type;
51 tp = canon(tp);
52 if( tp->t_op == ADDR )
53 tp = tp->t_left;
54 if( tp->t_op == CINT || tp->t_op == SYMBOL ) {
55 if( tp->t_op != CINT )
56 printf(".dc.l ");
57 else {
58 printf(".dc");
59 outtype(typeout);
1File: INTERF.C Page 2
60 putchar(' ');
61 }
62 outaexpr(tp,NOTIMMED); /* [vlh] 4.0 not immed... */
63 }
64 else
65 error("invalid initialization");
66 putchar('\n');
67 }
68 }
69
70 /* snalloc - code generator symbol node allocation*/
71 /* This might be coalesced into parser snalloc.*/
72 char *snalloc(type,sc,offset,dp,ssp) /* returns ptr to node alloced*/
73 int type; /* type of symbol*/
74 int sc; /* storage class*/
75 int offset; /* offset from Local Environment Ptr*/
76 int dp; /*for compatability with parser*/
77 int ssp; /*for compatability with parser*/
78 {
79 register struct symnode *sp;
80
81 sp = talloc(sizeof(*sp));
82 sp->t_op = SYMBOL;
83 sp->t_type = type;
84 sp->t_su = dp;
85 sp->t_ssp = ssp;
86 sp->t_sc = sc;
87 switch( sc ) {
88
89 case STATIC:
90 sp->t_offset = 0;
91 sp->t_reg = 0;
92 sp->t_label = offset;
93 break;
94
95 case REGISTER:
96 sp->t_offset = 0;
97 sp->t_reg = offset;
98 sp->t_label = 0;
99 break;
100
101 case AUTO:
102 sp->t_sc = REGOFF;
103 sp->t_offset = offset;
104 sp->t_reg = LEP;
105 sp->t_label = 0;
106 break;
107
108 default:
109 sp->t_offset = offset;
110 sp->t_reg = 0;
111 sp->t_label = 0;
112 break;
113 }
114 return(sp);
115 }
116
117 exprok(tp)
118 struct tnode *tp;
1File: INTERF.C Page 3
119 {
120 if( tp < exprarea || tp > &exprarea[EXPSIZE] )
121 return(0);
122 if( leafop(tp->t_op) )
123 return(1);
124 if( binop(tp->t_op) && !exprok(tp->t_right) )
125 return(0);
126 return( exprok(tp->t_left) );
127 }
128
129 outline()
130 {
131 if( onepass && !bol )
132 putchar('\n');
133 printf("*line %d\n",lineno);
134 }

View File

@@ -0,0 +1,12 @@
ren u.o=util.o
ren t.o=tabl.o
ren c.o=codegen.o
ren i.o=interf.o
ren m.o=main.o
ren p.o=putexpr.o
$1lo68 -r -f $1 -unofloat 0$1s.o canon.o c.o cskels.o i.o m.o optab.o p.o smatch.o sucomp.o t.o u.o 0$1lib6.a 0$1clib
era c168.rel
ren c168.rel=c.out
era *.o
user 0!make $1

View File

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

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
#define PDP11 1 /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
#define UNIX 1 /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,11 @@
1File: MACHINE.H Page 1
1 /*
2 * Use this file to determine what kind of machine you want the
3 * Alcyon stuff to run on ....
4 */
5 /*#define MC68000 1*/ /* 68000 version */
6 #define VAX 1 /* VAX Version */
7 /*#define PDP11 1*/ /* PDP-11 Version*/
8 /*#define CPM 1*/ /* CP/M Operating System*/
9 /*#define UNIX 1*/ /* UNIX Operating System*/
10 #define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,429 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version "@(#) c168 code generator 4.0 - Feb 10, 1983";
#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;
#ifdef VERSADOS
lflag++;
#endif
for( i = 3; i < argc; i++ ) {
q = argv[i];
if( *q++ != '-' )
usage(argc,argv,1);
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(argc,argv,2);
}
break;
}
}
if( argc < 3 )
usage(argc,argv,3);
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't open %s\n",argv[1]);
if( fcreat(argv[2],&obuf,0) < 0 ) /* 3rd arg for versados */
ferror("can't create %s\n",argv[2]);
readicode();
v6flush(&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 CFORREG:
outcforreg(tp->t_left);
break;
case IFGOTO:
outifgoto(tp->t_left,tp->t_type,tp->t_su);
break;
default:
outexpr(tp);
break;
}
}
break;
case '(':
while( (c=getc(&ibuf)) != '\n' )
putchar(c);
putchar(c);
break;
default:
error("intermediate code error %c,%d",c,c);
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 CFLOAT: /* [vlh] 3.4 */
l.hiword = readint();
l.loword = readint();
tp = fpcnalloc(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()) )
return(0);
if( !(rtp=readtree()) )
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 - %c,%d",c,c);
}
}
}
/* 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*/
/* returns ptr to node made.*/
char *tnalloc(op,type,info,dummy,left,right)
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);
}
/* fpcnalloc - allocate constant expression tree node*/
char *fpcnalloc(type,value) /* returns pointer to node alloced*/
int type; /* type of constant*/
long value; /* value of constant*/
{ /* [vlh] 3.4 */
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CFLOAT;
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(argc,argv,n)
char *argv[];
{
register int i;
error("usage call #%d:\n",n);
for (i=0; i<argc; i++) error(" argv[%d] = %s\n",i,argv[i]);
ferror("usage: c168 icode asm [-DLmec]");
}
/* 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*/
}
}
v6flush(v6b)
struct iobuf *v6b;
{
register i;
i = BLEN - v6b->nunused;
v6b->nunused = BLEN;
v6b->xfree = &(v6b->buff[0]);
if(write(v6b->fildes,v6b->xfree,i) != i)
return(-1);
return(0);
}
printf(string,a,b,c,d,e,f,g)
char *string;
int a,b,c,d,e,f,g;
{
char area[256];
register char *p;
sprintf(area,string,a,b,c,d,e,f,g);
for(p = &area[0]; *p; p++)
putchar(*p);
}

View File

@@ -0,0 +1,437 @@
1File: MAIN.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 char *version "@(#) c168 code generator 4.0 - Feb 10, 1983";
9
10 #include "cgen.h"
11 #include "cskel.h"
12 char *opap;
13 int errflg;
14 int nextlabel 10000;
15 char *readtree();
16 char *readsym();
17
18
19 /* main - main routine, handles arguments and files*/
20 main(argc,argv) /* returns - none*/
21 int argc; /* arg count*/
22 char **argv; /* arg pointers*/
23 {
24 register char *q;
25 register int i;
26
27 #ifdef VERSADOS
28 lflag++;
29 #endif
30 for( i = 3; i < argc; i++ ) {
31 q = argv[i];
32 if( *q++ != '-' )
33 usage(argc,argv,1);
34 while( 1 ) {
35 switch( *q++ ) {
36
37 case 'D':
38 case 'd':
39 dflag++;
40 continue;
41
42 case 'L':
43 case 'l':
44 lflag++;
45 continue;
46
47 case 'E':
48 case 'e':
49 eflag++;
50 continue;
51
52 case 'F':
53 case 'f':
54 fflag++;
55 continue;
56
57 case 'M':
58 case 'm':
59 mflag++;
1File: MAIN.C Page 2
60 continue;
61
62 case 'O':
63 case 'o':
64 oflag++;
65 continue;
66
67 case 'C':
68 case 'c':
69 cflag++;
70 continue;
71
72 case '\0':
73 break;
74
75 default:
76 usage(argc,argv,2);
77 }
78 break;
79 }
80 }
81 if( argc < 3 )
82 usage(argc,argv,3);
83 if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
84 ferror("can't open %s\n",argv[1]);
85 if( fcreat(argv[2],&obuf,0) < 0 ) /* 3rd arg for versados */
86 ferror("can't create %s\n",argv[2]);
87 readicode();
88 v6flush(&obuf);
89 exit(errcnt!=0);
90 }
91
92 /* readicode - read intermediate code and dispatch output*/
93 /* This copies assembler lines beginning with '(' to assembler*/
94 /* output and builds trees starting with '.' line.*/
95 readicode() /*returns - none*/
96 {
97 register int c;
98 register struct tnode *tp;
99
100 while( (c=getc(&ibuf)) > 0 ) {
101 switch(c) {
102
103 case '.':
104 lineno = readint();
105 opap = exprarea;
106 if( tp = readtree() ) {
107 #ifndef NODEBUG
108 if( cflag )
109 putexpr("readicode",tp);
110 #endif
111 switch( tp->t_op ) {
112
113 case INIT:
114 outinit(tp->t_left);
115 break;
116
117 case CFORREG:
118 outcforreg(tp->t_left);
1File: MAIN.C Page 3
119 break;
120
121 case IFGOTO:
122 outifgoto(tp->t_left,tp->t_type,tp->t_su);
123 break;
124
125 default:
126 outexpr(tp);
127 break;
128 }
129 }
130 break;
131
132 case '(':
133 while( (c=getc(&ibuf)) != '\n' )
134 putchar(c);
135 putchar(c);
136 break;
137
138 default:
139 error("intermediate code error %c,%d",c,c);
140 break;
141 }
142 }
143 }
144
145 /* readtree - recursive intermediate code tree read*/
146 char *readtree() /* returns ptr to expression tree*/
147 {
148 register int op, type, sc;
149 register struct tnode *tp, *rtp;
150 char sym[SSIZE];
151 long l;
152
153 if( (op=readint()) <= 0 )
154 return(0);
155 type = readint();
156 switch( op ) {
157
158 case SYMBOL:
159 if( (sc=readint()) == EXTERNAL )
160 tp = cenalloc(type,sc,readsym(sym));
161 else
162 tp = snalloc(type,sc,readint(),0,0);
163 break;
164
165 case CINT:
166 tp = cnalloc(type,readint());
167 break;
168
169 case CLONG:
170 l.hiword = readint();
171 l.loword = readint();
172 tp = lcnalloc(type,l);
173 break;
174
175 case CFLOAT: /* [vlh] 3.4 */
176 l.hiword = readint();
177 l.loword = readint();
1File: MAIN.C Page 4
178 tp = fpcnalloc(type,l);
179 break;
180
181 case IFGOTO:
182 case BFIELD:
183 sc = readint();
184 if( tp = readtree() )
185 tp = tnalloc(op,type,sc,0,tp,null);
186 break;
187
188 default:
189 if( binop(op) ) {
190 if( !(tp=readtree()) )
191 return(0);
192 if( !(rtp=readtree()) )
193 return(0);
194 tp = tnalloc(op,type,0,0,tp,rtp);
195 }
196 else if( tp = readtree() )
197 tp = tnalloc(op,type,0,0,tp,null);
198 break;
199 }
200 return(tp);
201 }
202
203 /* readint - reads an integer value from intermediate code*/
204 readint()
205 {
206 register int i, c;
207
208 i = 0;
209 while(1) {
210 switch( c = getc(&ibuf) ) {
211
212 case '.':
213 case '\n':
214 return(i);
215
216 case '0':
217 case '1':
218 case '2':
219 case '3':
220 case '4':
221 case '5':
222 case '6':
223 case '7':
224 case '8':
225 case '9':
226 i =<< 4;
227 i =+ (c-'0');
228 break;
229
230 case 'a':
231 case 'b':
232 case 'c':
233 case 'd':
234 case 'e':
235 case 'f':
236 i =<< 4;
1File: MAIN.C Page 5
237 i =+ (c-('a'-10));
238 break;
239
240 case 'A':
241 case 'B':
242 case 'C':
243 case 'D':
244 case 'E':
245 case 'F':
246 i =<< 4;
247 i =+ (c-('A'-10));
248 break;
249
250 default:
251 error("intermediate code error - %c,%d",c,c);
252 }
253 }
254 }
255
256 /* readsym - read a symbol from intermediate code*/
257 char *readsym(sym)
258 char *sym;
259 {
260 register int i, c;
261 register char *s;
262
263 for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; )
264 if( --i >= 0 )
265 *s++ = c;
266 if( i > 0 )
267 *s = '\0';
268 return(sym);
269 }
270
271 /* error - output an error message*/
272 error(s,x1,x2,x3,x4,x5,x6)
273 char *s;
274 int x1, x2, x3, x4, x5, x6;
275 {
276 errcnt++;
277 errflg++;
278 if( lineno != 0 )
279 printf("** %d: ",lineno);
280 printf(s,x1,x2,x3,x4,x5,x6);
281 putchar('\n');
282 errflg--;
283 }
284
285 /* ferror - output error message and die*/
286 ferror(s,x1,x2,x3,x4,x5,x6)
287 char *s;
288 int x1, x2, x3, x4, x5, x6;
289 {
290 error(s,x1,x2,x3,x4,x5,x6);
291 exit(1);
292 }
293
294 /* tnalloc - allocate binary expression tree node*/
295 /* returns ptr to node made.*/
1File: MAIN.C Page 6
296 char *tnalloc(op,type,info,dummy,left,right)
297 int op; /* operator*/
298 int type; /* resultant node type*/
299 int info; /* info field*/
300 int dummy; /* dummy field - used to match pass1 args*/
301 struct tnode *left; /* left sub-tree*/
302 struct tnode *right; /* righst sub-tree*/
303 {
304 register struct tnode *tp;
305
306 tp = talloc(sizeof(*tp));
307 tp->t_op = op;
308 tp->t_type = type;
309 tp->t_su = info; /* info for bit-field & condbr's*/
310 tp->t_left = left;
311 tp->t_right = right;
312 return(tp);
313 }
314
315 /* cnalloc - allocate constant expression tree node*/
316 char *cnalloc(type,value) /* returns pointer to node alloced*/
317 int type; /* type of constant*/
318 int value; /* value of constant*/
319 {
320 register struct conode *cp;
321
322 cp = talloc(sizeof(*cp));
323 cp->t_op = CINT;
324 cp->t_type = type;
325 cp->t_value = value;
326 return(cp);
327 }
328
329 /* lcnalloc - allocate constant expression tree node*/
330 char *lcnalloc(type,value) /* returns pointer to node alloced*/
331 int type; /* type of constant*/
332 long value; /* value of constant*/
333 {
334 register struct lconode *cp;
335
336 cp = talloc(sizeof(*cp));
337 cp->t_op = CLONG;
338 cp->t_type = type;
339 cp->t_lvalue = value;
340 return(cp);
341 }
342
343 /* fpcnalloc - allocate constant expression tree node*/
344 char *fpcnalloc(type,value) /* returns pointer to node alloced*/
345 int type; /* type of constant*/
346 long value; /* value of constant*/
347 { /* [vlh] 3.4 */
348 register struct lconode *cp;
349
350 cp = talloc(sizeof(*cp));
351 cp->t_op = CFLOAT;
352 cp->t_type = type;
353 cp->t_lvalue = value;
354 return(cp);
1File: MAIN.C Page 7
355 }
356
357 /* talloc - allocate expression tree area*/
358 char *talloc(size) /* returns pointer to area alloced*/
359 int size; /* number of bytes to alloc*/
360 {
361 register char *p;
362
363 p = opap;
364 if( p + size >= &exprarea[EXPSIZE] )
365 ferror("expression too complex");
366 opap = p + size;
367 return(p);
368 }
369
370 /* symcopy - copy symbol*/
371 symcopy(sym1,sym2) /* returns - none*/
372 char *sym1; /* from symbol*/
373 char *sym2; /* to symbol*/
374 {
375 register char *p, *q;
376 register int i;
377
378 for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
379 *q++ = (*p ? *p++ : '\0');
380 }
381
382 /* usage - ouput usage message*/
383 usage(argc,argv,n)
384 char *argv[];
385 {
386 register int i;
387 error("usage call #%d:\n",n);
388 for (i=0; i<argc; i++) error(" argv[%d] = %s\n",i,argv[i]);
389 ferror("usage: c168 icode asm [-DLmec]");
390 }
391
392 /* putchar - special version*/
393 /* This allows the use of printf for error messages, debugging*/
394 /* output and normal output.*/
395 putchar(c) /* returns - none*/
396 char c; /* character to output*/
397 {
398 if( errflg ) /*error message?*/
399 write(1,&c,1); /*write to standard output*/
400 else {
401 if( dflag > 1 )
402 write(1,&c,1); /*to standard output*/
403 putc(c,&obuf); /*put to assembler file*/
404 }
405 }
406
407 v6flush(v6b)
408 struct iobuf *v6b;
409 {
410 register i;
411
412 i = BLEN - v6b->nunused;
413 v6b->nunused = BLEN;
1File: MAIN.C Page 8
414 v6b->xfree = &(v6b->buff[0]);
415 if(write(v6b->fildes,v6b->xfree,i) != i)
416 return(-1);
417 return(0);
418 }
419 printf(string,a,b,c,d,e,f,g)
420 char *string;
421 int a,b,c,d,e,f,g;
422 {
423 char area[256];
424 register char *p;
425
426 sprintf(area,string,a,b,c,d,e,f,g);
427 for(p = &area[0]; *p; p++)
428 putchar(*p);
429 }

View File

@@ -0,0 +1,103 @@
$1stat machine.h=rw
$1pip machine.h=machine.68k
$1cp68 -i 0$1 CANON.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CANON.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u CANON.s
era CANON.s
$1cp68 -i 0$1 CODEGEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CODEGEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u CODEGEN.s
era CODEGEN.s
$1cp68 -i 0$1 CSKELS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CSKELS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u CSKELS.s
era CSKELS.s
$1cp68 -i 0$1 INTERF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic INTERF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u INTERF.s
era INTERF.s
$1cp68 -i 0$1 MAIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic MAIN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u MAIN.s
era MAIN.s
$1cp68 -i 0$1 OPTAB.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic OPTAB.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u OPTAB.s
era OPTAB.s
$1cp68 -i 0$1 PUTEXPR.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic PUTEXPR.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u PUTEXPR.s
era PUTEXPR.s
$1cp68 -i 0$1 SMATCH.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SMATCH.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u SMATCH.s
era SMATCH.s
$1cp68 -i 0$1 SUCOMP.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SUCOMP.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u SUCOMP.s
era SUCOMP.s
$1cp68 -i 0$1 TABL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic TABL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u TABL.s
era TABL.s
$1cp68 -i 0$1 UTIL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic UTIL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u UTIL.s
era UTIL.s
link $1

View File

@@ -0,0 +1,322 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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_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_EQADDR 29
#define FR_EQNOT 30
#define FE_EQNOT 31
#define FR_DOCAST 32
#define FS_DOCAST 33
#define FR_FTOL 34
#define FR_LTOF 35
#define FR_FTOI 36
#define FR_ITOF 37
#define FE_EQMULT 38
#define FE_EQDIV 39
#define FE_EQMOD 40
#define FR_TOCHAR 41
char
fe_eqop[], /* 1=FE_EQOP */
fe_assign[], /* 2=FE_ASSIGN */
fe_eqshft[], /* 3=FE_EQSHFT */
fe_eqxor[], /* 4=FE_EQXOR */
fe_eqaddr[], /* 5=FE_EQADDR */
fc_fix[], /* 6=FC_FIX */
fc_rel[], /* 7=FC_REL */
fc_btst[], /* 8=FC_BTST */
fs_op[], /* 9=FS_OP */
fs_itl[], /* 10=FS_ITL */
fs_ld[], /* 11=FS_LD */
fr_op[], /* 12=FR_OP */
fr_mult[], /* 13=FR_MULT */
fr_div[], /* 14=FR_DIV */
fr_shft[], /* 15=FR_SHFT */
fr_xor[], /* 16=FR_XOR */
fr_neg[], /* 17=FR_NEG */
fr_eqop[], /* 18=FR_EQOP */
fr_postop[], /* 19=FR_POSTOP */
fr_assign[], /* 20=FR_ASSIGN */
fr_eqmult[], /* 21=FR_EQMULT */
fr_eqdiv[], /* 22=FR_EQDIV */
fr_eqshft[], /* 23=FR_EQSHFT */
fr_eqxor[], /* 23=FR_EQXOR */
fr_call[], /* 24=FR_CALL */
fr_itl[], /* 25=FR_ITL */
fr_lti[], /* 26=FR_LTI */
fr_ld[], /* 27=FR_LD */
fr_eqaddr[], /* 28=FR_EQADDR */
fr_eqnot[], /* 29=FR_EQNOT */
fe_eqnot[], /* 30=FE_EQNOT */
fr_docast[], /* 31=FR_DOCAST */
fs_docast[], /* 32=FS_DOCAST */
fr_ftol[], /* 34=FE_FTOL */
fr_ltof[], /* 35=FE_LTOF */
fr_ftoi[], /* 36=FE_FTOI */
fr_itof[], /* 37=FE_ITOF */
fe_eqmult[], /* 38=FE_EQMULT */
fe_eqdiv[], /* 39=FE_EQDIV */
fe_eqmod[], /* 40=FE_EQMOD */
fr_tochar[]; /* 41=FR_TOCHAR */
char *codeskels[] {
0, /*NULL*/
fe_eqop, /*1=FE_EQOP*/
fe_assign, /*2=FE_ASSIGN*/
fe_eqshft, /*3=FE_EQSHFT*/
fe_eqxor, /*4=FE_EQXOR*/
fe_eqaddr, /*5=FE_EQADDR*/
fc_fix, /*6=FC_FIX*/
fc_rel, /*7=FC_REL*/
fc_btst, /*8=FC_BTST*/
fs_op, /*9=FS_OP*/
fs_itl, /*10=FS_ITL*/
fs_ld, /*11=FS_LD*/
fr_op, /*12=FR_OP*/
fr_mult, /*13=FR_MULT*/
fr_div, /*14=FR_DIV*/
fr_shft, /*15=FR_SHFT*/
fr_xor, /*16=FR_XOR*/
fr_neg, /*17=FR_NEG*/
fr_eqop, /*18=FR_EQOP*/
fr_postop, /*19=FR_POSTOP*/
fr_assign, /*20=FR_ASSIGN*/
fr_eqmult, /*21=FR_EQMULT*/
fr_eqdiv, /*22=FR_EQDIV*/
fr_eqshft, /*23=FR_EQSHFT*/
fr_eqxor, /*24=FR_EQXOR*/
fr_call, /*25=FR_CALL*/
fr_itl, /*26=FR_ITL*/
fr_lti, /*27=FR_LTI*/
fr_ld, /*28=FE_LD*/
fr_eqaddr, /*29=FE_EQADDR*/
fr_eqnot, /*30=FE_EQNOT*/
fe_eqnot, /*31=FE_EQNOT*/
fr_docast, /*32=FE_DOCAST*/
fs_docast, /*33=FS_DOCAST*/
fr_ftol, /*34=FE_FTOL*/
fr_ltof, /*35=FE_LTOF*/
fr_ftoi, /*36=FE_FTOI*/
fr_itof, /*37=FE_ITOF*/
fe_eqmult, /*38=FE_EQMULT*/
fe_eqdiv, /*39=FE_EQDIV*/
fe_eqmod, /*40=FE_EQMOD*/
fr_tochar, /*41=FR_TOCHAR*/
};
/*
*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, /*0=NULL*/
I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*1=ADD*/
I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*2=SUB*/
I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*3=MULT*/
I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*4=DIV*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*5=MOD*/
I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*6=RSH*/
I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*7=LSH*/
I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*8=AND*/
I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*9=OR*/
I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*10=XOR*/
I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*11=NOT*/
I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*12=NEG*/
I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*13=COMPL*/
I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*14=PREDEC*/
I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*15=PREINC*/
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*16=POSTDEC*/
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*17=POSTINC*/
I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*18=ASSIGN*/
I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*19=EQADD*/
I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*20=EQSUB*/
I_MULS, I_MULU, FE_EQMULT, FC_FIX, I_NULL, FR_EQMULT, /*21=EQMULT*/
I_DIVS, I_DIVU, FE_EQDIV, FC_FIX, I_NULL, FR_EQDIV, /*22=EQDIV*/
I_DIVS, I_DIVU, FE_EQMOD, I_NULL, I_NULL, FR_EQDIV, /*23=EQMOD*/
I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*24=EQRSH*/
I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*25=EQLSH*/
I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*26=EQAND*/
I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*27=EQOR*/
I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*28=EQXOR*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*29=FJSR*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*30=EQUALS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*31=NEQUALS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*32=GREAT*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*33=GREATEQ*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*34=LESS*/
I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*35=LESSEQ*/
I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*36=INT2L*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*37=LONG2I*/
I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*38=BTST*/
I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*39=LOAD*/
I_MULS, I_MULU, I_NULL, I_NULL, I_NULL, FR_MULT, /*40=LMULT*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*41=LDIV*/
I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*42=LMOD*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*43=NULL*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*44=NULL*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*45=NULL*/
I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*46=EQADDR*/
I_NOT, I_NOT, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*47=EQNOT*/
I_NEG, I_NEG, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*48=EQNEG*/
I_NULL, I_NULL, I_NULL, I_NULL, FS_DOCAST, FR_DOCAST, /*49=DOCAST*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*50=STASSIGN*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTOF, /*51=LONG2F*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOL, /*52=FLOAT2L*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_ITOF, /*53=INT2F*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOI, /*54=FLOAT2I*/
I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_TOCHAR, /*55=TOCHAR*/
};
/*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,328 @@
1File: OPTAB.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9
10 #define I_NULL 0
11 #define I_ADD 1
12 #define I_INC 2
13 #define I_SUB 3
14 #define I_DEC 4
15 #define I_MULS 5
16 #define I_MULU 6
17 #define I_DIVS 7
18 #define I_DIVU 8
19 #define I_ASR 9
20 #define I_LSR 10
21 #define I_ASL 11
22 #define I_LSL 12
23 #define I_AND 13
24 #define I_OR 14
25 #define I_EOR 15
26 #define I_NEG 16
27 #define I_NOT 17
28 #define I_MOVE 18
29 #define I_CLR 19
30 #define I_CMP 20
31 #define I_TST 21
32 #define I_LMUL 22
33 #define I_LDIV 23
34 #define I_LREM 24
35 #define I_LEML 25
36 #define I_LERM 27
37 #define I_BEQ 28
38 #define I_BNE 29
39 #define I_BGT 30
40 #define I_BGE 31
41 #define I_BLT 32
42 #define I_BLE 33
43 #define I_BLS 34
44 #define I_BLO 35
45 #define I_BCC 36
46 #define I_BHI 37
47 #define I_BRA 38
48 #define I_NOP 39
49 #define I_BTST 40
50
51 char *mnemonics[] {
52 "",
53 "add",
54 "inc",
55 "sub",
56 "dec",
57 "muls",
58 "mulu",
59 "divs",
1File: OPTAB.C Page 2
60 "divu",
61 "asr",
62 "lsr",
63 "asl",
64 "lsl",
65 "and",
66 "or",
67 "eor",
68 "neg",
69 "not",
70 "move",
71 "clr",
72 "cmp",
73 "tst",
74 "lmul",
75 "_ldiv",
76 "lrem",
77 "almul",
78 "aldiv",
79 "alrem",
80 "beq",
81 "bne",
82 "bgt",
83 "bge",
84 "blt",
85 "ble",
86 "bls",
87 "blo",
88 "bcc",
89 "bhi",
90 "jmp",
91 "*nop",
92 "btst",
93 };
94
95 #define FE_EQOP 1
96 #define FE_ASSIGN 2
97 #define FE_EQSHFT 3
98 #define FE_EQXOR 4
99 #define FE_EQADDR 5
100 #define FC_FIX 6
101 #define FC_REL 7
102 #define FC_BTST 8
103 #define FS_OP 9
104 #define FS_ITL 10
105 #define FS_LD 11
106 #define FR_ADD 12
107 #define FR_MULT 13
108 #define FR_DIV 14
109 #define FR_SHFT 15
110 #define FR_XOR 16
111 #define FR_NEG 17
112 #define FR_EQOP 18
113 #define FR_POSTOP 19
114 #define FR_ASSIGN 20
115 #define FR_EQMULT 21
116 #define FR_EQDIV 22
117 #define FR_EQSHFT 23
118 #define FR_EQXOR 24
1File: OPTAB.C Page 3
119 #define FR_CALL 25
120 #define FR_ITL 26
121 #define FR_LTI 27
122 #define FR_LD 28
123 #define FR_EQADDR 29
124 #define FR_EQNOT 30
125 #define FE_EQNOT 31
126 #define FR_DOCAST 32
127 #define FS_DOCAST 33
128 #define FR_FTOL 34
129 #define FR_LTOF 35
130 #define FR_FTOI 36
131 #define FR_ITOF 37
132 #define FE_EQMULT 38
133 #define FE_EQDIV 39
134 #define FE_EQMOD 40
135 #define FR_TOCHAR 41
136
137 char
138 fe_eqop[], /* 1=FE_EQOP */
139 fe_assign[], /* 2=FE_ASSIGN */
140 fe_eqshft[], /* 3=FE_EQSHFT */
141 fe_eqxor[], /* 4=FE_EQXOR */
142 fe_eqaddr[], /* 5=FE_EQADDR */
143 fc_fix[], /* 6=FC_FIX */
144 fc_rel[], /* 7=FC_REL */
145 fc_btst[], /* 8=FC_BTST */
146 fs_op[], /* 9=FS_OP */
147 fs_itl[], /* 10=FS_ITL */
148 fs_ld[], /* 11=FS_LD */
149 fr_op[], /* 12=FR_OP */
150 fr_mult[], /* 13=FR_MULT */
151 fr_div[], /* 14=FR_DIV */
152 fr_shft[], /* 15=FR_SHFT */
153 fr_xor[], /* 16=FR_XOR */
154 fr_neg[], /* 17=FR_NEG */
155 fr_eqop[], /* 18=FR_EQOP */
156 fr_postop[], /* 19=FR_POSTOP */
157 fr_assign[], /* 20=FR_ASSIGN */
158 fr_eqmult[], /* 21=FR_EQMULT */
159 fr_eqdiv[], /* 22=FR_EQDIV */
160 fr_eqshft[], /* 23=FR_EQSHFT */
161 fr_eqxor[], /* 23=FR_EQXOR */
162 fr_call[], /* 24=FR_CALL */
163 fr_itl[], /* 25=FR_ITL */
164 fr_lti[], /* 26=FR_LTI */
165 fr_ld[], /* 27=FR_LD */
166 fr_eqaddr[], /* 28=FR_EQADDR */
167 fr_eqnot[], /* 29=FR_EQNOT */
168 fe_eqnot[], /* 30=FE_EQNOT */
169 fr_docast[], /* 31=FR_DOCAST */
170 fs_docast[], /* 32=FS_DOCAST */
171 fr_ftol[], /* 34=FE_FTOL */
172 fr_ltof[], /* 35=FE_LTOF */
173 fr_ftoi[], /* 36=FE_FTOI */
174 fr_itof[], /* 37=FE_ITOF */
175 fe_eqmult[], /* 38=FE_EQMULT */
176 fe_eqdiv[], /* 39=FE_EQDIV */
177 fe_eqmod[], /* 40=FE_EQMOD */
1File: OPTAB.C Page 4
178 fr_tochar[]; /* 41=FR_TOCHAR */
179
180 char *codeskels[] {
181 0, /*NULL*/
182 fe_eqop, /*1=FE_EQOP*/
183 fe_assign, /*2=FE_ASSIGN*/
184 fe_eqshft, /*3=FE_EQSHFT*/
185 fe_eqxor, /*4=FE_EQXOR*/
186 fe_eqaddr, /*5=FE_EQADDR*/
187 fc_fix, /*6=FC_FIX*/
188 fc_rel, /*7=FC_REL*/
189 fc_btst, /*8=FC_BTST*/
190 fs_op, /*9=FS_OP*/
191 fs_itl, /*10=FS_ITL*/
192 fs_ld, /*11=FS_LD*/
193 fr_op, /*12=FR_OP*/
194 fr_mult, /*13=FR_MULT*/
195 fr_div, /*14=FR_DIV*/
196 fr_shft, /*15=FR_SHFT*/
197 fr_xor, /*16=FR_XOR*/
198 fr_neg, /*17=FR_NEG*/
199 fr_eqop, /*18=FR_EQOP*/
200 fr_postop, /*19=FR_POSTOP*/
201 fr_assign, /*20=FR_ASSIGN*/
202 fr_eqmult, /*21=FR_EQMULT*/
203 fr_eqdiv, /*22=FR_EQDIV*/
204 fr_eqshft, /*23=FR_EQSHFT*/
205 fr_eqxor, /*24=FR_EQXOR*/
206 fr_call, /*25=FR_CALL*/
207 fr_itl, /*26=FR_ITL*/
208 fr_lti, /*27=FR_LTI*/
209 fr_ld, /*28=FE_LD*/
210 fr_eqaddr, /*29=FE_EQADDR*/
211 fr_eqnot, /*30=FE_EQNOT*/
212 fe_eqnot, /*31=FE_EQNOT*/
213 fr_docast, /*32=FE_DOCAST*/
214 fs_docast, /*33=FS_DOCAST*/
215 fr_ftol, /*34=FE_FTOL*/
216 fr_ltof, /*35=FE_LTOF*/
217 fr_ftoi, /*36=FE_FTOI*/
218 fr_itof, /*37=FE_ITOF*/
219 fe_eqmult, /*38=FE_EQMULT*/
220 fe_eqdiv, /*39=FE_EQDIV*/
221 fe_eqmod, /*40=FE_EQMOD*/
222 fr_tochar, /*41=FR_TOCHAR*/
223 };
224 /*
225 *This is the major table directing the code generation process.
226 *It is indexed by an O_op operator, which is obtained from the
227 *opinfo table for an intermediate code operator. The actual
228 *code skeleton macros are in cskels.c, which are in a linked
229 *list in order of decreasing order of difficulty.
230 */
231 char optab[][6] {
232
233 /* I I2 effect cc's stack register*/
234
235 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*0=NULL*/
236 I_ADD, I_INC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*1=ADD*/
1File: OPTAB.C Page 5
237 I_SUB, I_DEC, I_NULL, FC_FIX, FS_OP, FR_ADD, /*2=SUB*/
238 I_MULS, I_MULU, I_NULL, FC_FIX, I_NULL, FR_MULT, /*3=MULT*/
239 I_DIVS, I_DIVU, I_NULL, FC_FIX, I_NULL, FR_DIV, /*4=DIV*/
240 I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*5=MOD*/
241 I_ASR, I_LSR, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*6=RSH*/
242 I_ASL, I_LSL, I_NULL, FC_FIX, I_NULL, FR_SHFT, /*7=LSH*/
243 I_AND, I_AND, I_NULL, FC_FIX, FS_OP, FR_ADD, /*8=AND*/
244 I_OR, I_OR, I_NULL, FC_FIX, FS_OP, FR_ADD, /*9=OR*/
245 I_EOR, I_EOR, I_NULL, FC_FIX, I_NULL, FR_XOR, /*10=XOR*/
246 I_NULL, I_NULL, I_NULL, FC_FIX, I_NULL, I_NULL, /*11=NOT*/
247 I_NEG, I_NEG, I_NULL, FC_FIX, I_NULL, FR_NEG, /*12=NEG*/
248 I_NOT, I_NOT, I_NULL, I_NULL, I_NULL, FR_NEG, /*13=COMPL*/
249 I_SUB, I_DEC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*14=PREDEC*/
250 I_ADD, I_INC, FE_EQOP, FC_FIX, I_NULL, FR_EQOP, /*15=PREINC*/
251 I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*16=POSTDEC*/
252 I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_POSTOP, /*17=POSTINC*/
253 I_MOVE, I_CLR, FE_ASSIGN, I_NULL, I_NULL, FR_ASSIGN, /*18=ASSIGN*/
254 I_ADD, I_INC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*19=EQADD*/
255 I_SUB, I_DEC, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*20=EQSUB*/
256 I_MULS, I_MULU, FE_EQMULT, FC_FIX, I_NULL, FR_EQMULT, /*21=EQMULT*/
257 I_DIVS, I_DIVU, FE_EQDIV, FC_FIX, I_NULL, FR_EQDIV, /*22=EQDIV*/
258 I_DIVS, I_DIVU, FE_EQMOD, I_NULL, I_NULL, FR_EQDIV, /*23=EQMOD*/
259 I_ASR, I_LSR, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*24=EQRSH*/
260 I_ASL, I_LSL, FE_EQSHFT, I_NULL, I_NULL, FR_EQSHFT, /*25=EQLSH*/
261 I_AND, I_AND, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*26=EQAND*/
262 I_OR, I_OR, FE_EQOP, I_NULL, I_NULL, FR_EQOP, /*27=EQOR*/
263 I_EOR, I_EOR, FE_EQXOR, FC_FIX, I_NULL, FR_EQXOR, /*28=EQXOR*/
264 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_CALL, /*29=FJSR*/
265 I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*30=EQUALS*/
266 I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*31=NEQUALS*/
267 I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*32=GREAT*/
268 I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*33=GREATEQ*/
269 I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*34=LESS*/
270 I_CMP, I_TST, I_NULL, FC_REL, I_NULL, I_NULL, /*35=LESSEQ*/
271 I_NULL, I_NULL, I_NULL, I_NULL, FS_ITL, FR_ITL, /*36=INT2L*/
272 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTI, /*37=LONG2I*/
273 I_BTST, I_BTST, I_NULL, FC_BTST, I_NULL, I_NULL, /*38=BTST*/
274 I_CMP, I_TST, I_NULL, FC_REL, FS_LD, FR_LD, /*39=LOAD*/
275 I_MULS, I_MULU, I_NULL, I_NULL, I_NULL, FR_MULT, /*40=LMULT*/
276 I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*41=LDIV*/
277 I_DIVS, I_DIVU, I_NULL, I_NULL, I_NULL, FR_DIV, /*42=LMOD*/
278 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*43=NULL*/
279 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*44=NULL*/
280 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*45=NULL*/
281 I_NULL, I_NULL, FE_EQADDR, I_NULL, I_NULL, FR_EQADDR, /*46=EQADDR*/
282 I_NOT, I_NOT, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*47=EQNOT*/
283 I_NEG, I_NEG, FE_EQNOT, I_NULL, I_NULL, FR_EQNOT, /*48=EQNEG*/
284 I_NULL, I_NULL, I_NULL, I_NULL, FS_DOCAST, FR_DOCAST, /*49=DOCAST*/
285 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, /*50=STASSIGN*/
286 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_LTOF, /*51=LONG2F*/
287 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOL, /*52=FLOAT2L*/
288 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_ITOF, /*53=INT2F*/
289 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_FTOI, /*54=FLOAT2I*/
290 I_NULL, I_NULL, I_NULL, I_NULL, I_NULL, FR_TOCHAR, /*55=TOCHAR*/
291 };
292
293
294 /*this maps comparison operators and comparison types into the*/
295 /*actual branch opcode used.*/
1File: OPTAB.C Page 6
296 char brtab[][2] {
297 I_BEQ, I_BEQ, /*EQUALS*/
298 I_BNE, I_BNE, /*NEQUALS*/
299 I_BGT, I_BHI, /*GREAT*/
300 I_BGE, I_BCC, /*GREATEQ*/
301 I_BLT, I_BLO, /*LESS*/
302 I_BLE, I_BLS, /*LESSEQ*/
303 };
304
305 /*turns !x>y into x<=y*/
306 int invrel[] { NEQUALS, EQUALS, LESSEQ, LESS, GREATEQ, GREAT };
307
308 /*turns x>y into y<=x*/
309 int swaprel[] { EQUALS, NEQUALS, LESS, LESSEQ, GREAT, GREATEQ };
310
311 /*code skeleton built-in strings*/
312 char *strtab[] {
313 "move", /*MOV*/
314 "move.l", /*MOVL*/
315 "jsr", /*JSR*/
316 "clr", /*CLR*/
317 "clr.l", /*CLRL*/
318 "ext.w", /*EXTW*/
319 "ext.l", /*EXTL*/
320 "lea", /*LEA*/
321 "(sp)", /*STK*/
322 };

View File

@@ -0,0 +1,255 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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*/
"=not", /*47*/
"=neg", /*48*/
"docast", /*49*/
"st=", /*50*/
"long->float", /*51*/
"float->long", /*52*/
"int->float", /*53*/
"float->int", /*54*/
"tochar", /*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*/
"float", /*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",
"veryhard",
};
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:
case CFLOAT: /*[vlh] 3.4 */
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:
case CFINDR: /* [vlh] 3.4 */
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,260 @@
1File: PUTEXPR.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9 #ifndef NODEBUG
10
11 char invalid[] "INVALID";
12
13 char *opname[] {
14 invalid, /*0*/
15 "+", /*1*/
16 "-", /*2*/
17 "*", /*3*/
18 "/", /*4*/
19 "%", /*5*/
20 ">>", /*6*/
21 "<<", /*7*/
22 "&", /*8*/
23 "|", /*9*/
24 "^", /*10*/
25 "!", /*11*/
26 "U-", /*12*/
27 "~", /*13*/
28 "--p", /*14*/
29 "++p", /*15*/
30 "p--", /*16*/
31 "p++", /*17*/
32 "=", /*18*/
33 "+=", /*19*/
34 "-=", /*20*/
35 "*=", /*21*/
36 "/=", /*22*/
37 "%=", /*23*/
38 ">>=", /*24*/
39 "<<=", /*25*/
40 "&=", /*26*/
41 "|=", /*27*/
42 "^=", /*28*/
43 "jsr", /*29*/
44 "==", /*30*/
45 "!=", /*31*/
46 ">", /*32*/
47 ">=", /*33*/
48 "<", /*34*/
49 "<=", /*35*/
50 "int->long", /*36*/
51 "long->int", /*37*/
52 "btst", /*38*/
53 "load", /*39*/
54 "long*", /*40*/
55 "long/", /*41*/
56 "long%", /*42*/
57 "long*=", /*43*/
58 "long/=", /*44*/
59 "long%=", /*45*/
1File: PUTEXPR.C Page 2
60 "=addr", /*46*/
61 "=not", /*47*/
62 "=neg", /*48*/
63 "docast", /*49*/
64 "st=", /*50*/
65 "long->float", /*51*/
66 "float->long", /*52*/
67 "int->float", /*53*/
68 "float->int", /*54*/
69 "tochar", /*55*/
70 invalid, /*56*/
71 invalid, /*57*/
72 invalid, /*58*/
73 invalid, /*59*/
74 "U&", /*60*/
75 "U*", /*61*/
76 "&&", /*62*/
77 "||", /*63*/
78 "?", /*64*/
79 ":", /*65*/
80 ",", /*66*/
81 "cint", /*67*/
82 "clong", /*68*/
83 "symbol", /*69*/
84 "++a", /*70*/
85 "a--", /*71*/
86 "call", /*72*/
87 "call()", /*73*/
88 "bitfield", /*74*/
89 "if", /*75*/
90 "init", /*76*/
91 "loadR0", /*77*/
92 "divlong", /*78*/
93 };
94
95 char *types[] {
96 invalid, /*0=TYPELESS*/
97 "char", /*1=CHAR*/
98 invalid, /*2=SHORT*/
99 "int", /*3=INT*/
100 "long", /*4=LONG*/
101 invalid, /*5=UCHAR*/
102 invalid, /*6=USHORT*/
103 "uint", /*7=UINT*/
104 invalid, /*8=ULONG*/
105 "float", /*9=FLOAT*/
106 invalid, /*10=DOUBLE*/
107 "struct", /*11=STRUCT*/
108 invalid, /*12=undefined*/
109 invalid, /*13=undefined*/
110 invalid, /*14=undefined*/
111 invalid, /*15=undefined*/
112 };
113
114 char *suvals[] {
115 "zero",
116 "one",
117 "quick",
118 "small",
1File: PUTEXPR.C Page 3
119 "constant",
120 "Areg",
121 "Dreg",
122 "addressable",
123 "loadable",
124 "easy",
125 "hard",
126 "veryhard",
127 };
128
129 int level;
130
131 putexpr(name,tp)
132 char *name;
133 struct tnode *tp;
134 {
135 printf("%s\n",name);
136 putsexpr(tp);
137 }
138
139 putsexpr(tp)
140 struct tnode *tp;
141 {
142 register struct tnode *ltp;
143
144 level++;
145 ltp = tp->t_left;
146 outlevel();
147 printf("%s ",opname[tp->t_op]);
148 if( tp->t_op == BFIELD || tp->t_op == IFGOTO ) {
149 if( tp->t_op == BFIELD )
150 printf("off=%d len=%d\n",(tp->t_su>>8)&0377,tp->t_su&0377);
151 else
152 printf("%s goto L%d\n",tp->t_type?"TRUE":"FALSE",tp->t_su);
153 putsexpr(tp->t_left);
154 level--;
155 return;
156 }
157 puttsu(tp);
158 switch( tp->t_op ) {
159
160 case DCLONG:
161 case CLONG:
162 case CFLOAT: /*[vlh] 3.4 */
163 printf(" %x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
164 break;
165
166
167 case CINT:
168 printf(" %d\n",tp->t_value);
169 break;
170
171 case AUTODEC:
172 case AUTOINC:
173 printf(" R%d\n",tp->t_reg);
174 break;
175
176 case SYMBOL:
177 switch( tp->t_sc ) {
1File: PUTEXPR.C Page 4
178
179 case REGISTER:
180 printf(" R%d",tp->t_reg);
181 break;
182
183 case CINDR:
184 printf(" %d\n",tp->t_offset);
185 break;
186
187 case CLINDR:
188 case CFINDR: /* [vlh] 3.4 */
189 printf(" %x.%x\n",tp->t_offset,tp->t_ssp);
190 break;
191
192 case REGOFF:
193 printf(" %d(R%d)",tp->t_offset,tp->t_reg);
194 break;
195
196 case EXTERNAL:
197 case EXTOFF:
198 printf(" %s+%d",tp->t_symbol,tp->t_offset);
199 if( tp->t_sc == EXTOFF )
200 printf("(R%d)",tp->t_reg);
201 break;
202
203 case STATIC:
204 case STATOFF:
205 printf(" L%d+%d",tp->t_label,tp->t_offset);
206 if( tp->t_sc == STATOFF )
207 printf("(R%d)",tp->t_reg);
208 break;
209
210 case INDEXED:
211 printf(" %d(R%d,R%d)",tp->t_offset,tp->t_reg,tp->t_xreg);
212 break;
213 }
214 putchar('\n');
215 break;
216
217 case IFGOTO:
218 putsexpr(tp->t_left);
219 break;
220
221 default:
222 putchar('\n');
223 putsexpr(tp->t_left);
224 if( binop(tp->t_op) )
225 putsexpr(tp->t_right);
226 break;
227 }
228 level--;
229 }
230
231 outlevel()
232 {
233 register int i;
234
235 for( i = 0; i < level; i++ )
236 putchar('\t');
1File: PUTEXPR.C Page 5
237 }
238
239 puttsu(tp)
240 struct tnode *tp;
241 {
242 register int i;
243
244 if( suptype(tp->t_type) )
245 putchar('*');
246 printf("%s ",types[btype(tp->t_type)]);
247 if( tp->t_su != 0 || (tp->t_op == CINT && tp->t_value == 0) ) {
248 i = tp->t_su >> 8;
249 if( i > 15 || i < 0 )
250 printf("INVALID");
251 else
252 printf("%s",suvals[tp->t_su>>8]);
253 }
254 }
255 #endif

View File

@@ -0,0 +1,20 @@
E:SEND CANON.C
E:SEND CODEGEN.C
E:SEND CSKELS.C
E:SEND INTERF.C
E:SEND MAIN.C
E:SEND OPTAB.C
E:SEND PUTEXPR.C
E:SEND SMATCH.C
E:SEND SUCOMP.C
E:SEND TABL.C
E:SEND UTIL.C
E:SEND VERSION.C
E:SEND CGEN.H
E:SEND CSKEL.H
E:SEND ICODE.H
E:SEND MACHINE.68K
E:SEND LINK.SUB
E:SEND MAKE.SUB
E:SEND MACHINE.H
E:SEND SEND13.SUB

View File

@@ -0,0 +1,517 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/* Code Skeleton expansion and matching */
#include "cgen.h"
#include "cskel.h"
#define SK_TYPE(x) (x&017)
/* expand - code skeleton expansion*/
/* Handles the expansion of code skeleton macros.*/
expand(tp,cookie,freg,skp) /* returns register result is in*/
struct tnode *tp; /* pointer to expression tree*/
int cookie; /* goal of expression tree*/
int freg; /* register to leave results in*/
struct skeleton *skp; /* pointer to code skeleton*/
{
register int op, nreg, reg;
register int c;
register int extf, i2f;
register struct tnode *ltp, *rtp;
register char *p;
register int i, inaddreg, sreg, flag, subtrees, scookie;
register char *macro;
#ifndef NODEBUG
if( eflag )
printf("expand op=%d left=%x right=%x skp=%o\n",tp->t_op,
skp->sk_left,skp->sk_right,skp);
#endif
if( ((op=tp->t_op) >= MULT && op <= XOR) || tp->t_type == CHAR )
freg = dreg(freg);
macro = skp->sk_def;
extf = 0;
i2f = 0;
rtp = ltp = tp->t_left;
subtrees = 1;
if( binop(op) ) {
subtrees++;
rtp = tp->t_right;
if( (longorptr(tp->t_type)) && (op == DIV || op == MOD ||
(op != MULT && (isdreg(freg)) &&
!(longorptr(ltp->t_type)) && !(longorptr(rtp->t_type)))) )
extf++;
switch( op ) {
case RSH:
case LSH:
case EQLSH:
case EQRSH:
if( unsign(ltp->t_type) )
i2f++;
break;
case MULT:
case EQMULT:
case DIV:
case MOD:
case EQDIV:
case EQMOD:
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
i2f++;
break;
}
}
nreg = freg + 1;
while( c = *macro++ ) {
c =& 0xff;
switch( c ) {
default:
putchar(c);
break;
case POP:
stacksize--;
printf("(sp)+");
break;
case POP4:
stacksize--;
popstack(4);
break;
case POP8:
stacksize =- 2;
popstack(8);
break;
case PSH:
if( cookie == FORSP ) /*don't affect sp*/
printf("(sp)");
else
printf("-(sp)");
stacksize++;
break;
case MOV:
case MOVL:
case JSR:
case CLR:
case CLRL:
case EXTW:
case EXTL:
case LEA:
case STK:
printf("%s",strtab[c-128]);
break;
case OPCALL:
if( isfloat(tp->t_type) || isfloat(ltp->t_type) ) {
switch( op ) {
case ADD:
case EQADD:
printf("_fpadd");
break;
case SUB:
case EQSUB:
printf("_fpsub");
break;
case MULT:
case EQMULT:
printf("_fpmult");
break;
case DIV:
case EQDIV:
printf("_fpdiv");
break;
case UMINUS:
case EQNEG:
printf("_fpneg");
break;
case FLOAT2L:
case FLOAT2I:
printf("_fpftol");
break;
case LONG2F:
case INT2F:
printf("_fpltof");
break;
case EQUALS:
case NEQUALS:
case GREAT:
case GREATEQ:
case LESS:
case LESSEQ:
printf("_fpcmp");
break;
default:
error("invalid floating op %d\n",op);
break;
}
}
else {
switch( op ) {
case MULT:
case LMULT:
printf("lmul");
break;
case DIV:
case LDIV:
printf("ldiv");
break;
case MOD:
case LMOD:
printf("lrem");
break;
default:
error("opcall bad op %d",op);
break;
}
}
break;
case TLEFT:
outtype( leafop(op) ? tp->t_type : ltp->t_type );
break;
case TLEFTL:
outatype( leafop(op) ? tp->t_type : ltp->t_type );
break;
case TEITHER:
if( longorptr(rtp->t_type) || longorptr(ltp->t_type) )
outtype(LONG);
break;
case TRIGHT:
outtype(rtp->t_type);
break;
case OP:
case AOP:
if( c == AOP || i2f )
i = optab[op][1];
else
i = optab[op][0];
printf(mnemonics[i]);
break;
case LADDR:
case RADDR:
p = (c==RADDR?rtp:ltp);
outaexpr(p,IMMED);
break;
case CR:
outcreg(freg);
break;
case NR:
outcreg(nreg);
break;
case CAR:
outcreg(areg(freg));
break;
case NAR:
outcreg(areg(nreg));
break;
case EXL:
outextend(ltp,LONG,freg);
break;
case EXRL:
case EXRLN:
outextend(rtp,ltp->t_type,c==EXRL?freg:nreg);
break;
case EXLR:
case EXLRN:
outextend(ltp,rtp->t_type,c==EXLR?freg:nreg);
break;
case LEFT:
case RIGHT:
subtrees--;
case TREE:
p = (c==LEFT?ltp:c==RIGHT?rtp:tp);
flag = *macro++;
scookie = FORREG;
if( flag & S_STACK ) {
if( cookie == FORSP )
scookie = FORSP;
else
scookie = FORSTACK;
}
else if( flag & S_FORCC )
scookie = FORCC;
if( flag & S_NEXT )
reg = nreg;
else
reg = freg;
if( flag & S_INDR ) {
if( p->t_op != INDR )
error("code skeleton error: %d\n",op);
p = p->t_left; /*skip INDR*/
if( coffset(p) ) {
p = p->t_left;
if( longorptr(p->t_type) == 0 && (flag&S_STACK) != 0 )
p = tnalloc(INT2L,LONG,0,0,p);
}
reg = areg(reg);
}
sreg = codegen(p,scookie,reg); /*code for subtree*/
if( scookie == FORREG ) {
if( flag & S_INDR ) {
if( isdreg(sreg) )
outmovr(sreg,areg(reg),p);
}
else if( flag & S_NEXT )
nreg = sreg;
else if( sreg != reg ) {
/*
* result was not in expected register, if remaining sub-tree can be
* compiled using the remaining registers, update current and next
* registers, saving us the trouble of moving the register.
*/
if( c == TREE || ((isdreg(sreg)) && subtrees > 0 &&
((c == LEFT &&
sucomp(rtp,sreg,0) <= skp->sk_right &&
sucomp(rtp,sreg,1) <= SU_ANY) ||
( c == RIGHT &&
sucomp(ltp,sreg,0) <= skp->sk_left &&
sucomp(ltp,sreg,1) <= SU_ANY))) ) {
freg = dreg(sreg);
nreg = freg + 1;
}
else
outmovr(sreg,dreg(freg),p);
}
}
break;
case LOFFSET:
case ROFFSET:
p = (c==LOFFSET) ? ltp->t_left : rtp->t_left;
if((p=coffset(p)) != 0 && (p->t_op != CINT || p->t_value != 0))
outaexpr(p,NOTIMMED);
break;
case MODSWAP:
switch( op ) {
case MOD:
case EQMOD:
case LMOD:
case LEQMOD:
outswap(freg);
}
break;
}
}
if( extf && cookie == FORREG && (isdreg(freg)) ) {
if( unsign(ltp->t_type) || unsign(rtp->t_type) )
outuext(freg);
else
outext(freg);
}
#ifndef NODEBUG
if( eflag )
printf("ending expand skp=%o\n",skp);
#endif
return(freg);
}
/*
* match - try to match expression tree with code skeleton
* Given the expression tree, tries to match the given tree with
* the appropriate code skeleton. The code skeleton list is
* gotten from the root operator and the cookie value. The code
* skeleton list is then searched, checking the Sethy-Ullman numbers
* of the sub-trees against the Sethy-Ullman numbers in the code
* skeleton list. If the Sethy-Ullman numbers are OK, then the
* left and right sub-trees are checked for compatability, e.g.
* integer pointers, etc. If a match is found, the code skeleton
* list pointer is returned.
*/
char *match(tp,cookie,reg) /* returns ptr to code skeleton*/
/* or 0 if no skeleton*/
struct tnode *tp; /* pointer to tree*/
int cookie; /* goal for code expansion*/
int reg; /* register to use*/
{
register struct skeleton *skp;
register int op, bop, opndx;
int i;
register struct tnode *ltp, *rtp;
#ifndef NODEBUG
if( mflag )
printf("match op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
#endif
if( (op=tp->t_op) >= LCGENOP )
return(0);
if( leafop(op) )
ltp = tp;
else
ltp = tp->t_left;
if( (bop=binop(op)) ) {
rtp = tp->t_right;
if( convop(ltp->t_op) ) {
if( op != LSH && notconvop(rtp->t_op) ) {
if( !(unsign(ltp->t_left->t_type)) || op == ASSIGN ) {
tp->t_left = ltp->t_left;
if( (skp=match(tp,cookie,reg)) != 0 )
return(skp);
tp->t_left = ltp;
}
}
}
else if( convop(rtp->t_op) ) {
if( !(unsign(rtp->t_left->t_type)) || op == ASSIGN ) {
tp->t_right = rtp->t_left;
if( (skp=match(tp,cookie,reg)) != 0 )
return(skp);
tp->t_right = rtp;
}
}
}
switch( cookie ) {
case FORCC:
i = 3;
break;
case FOREFF:
i = 2;
break;
case FORSTACK:
case FORSP:
i = 4;
break;
case FORREG:
i = 5;
break;
default:
error("match cookie=%d\n",cookie);
return(0);
}
#ifndef NODEBUG
if( mflag )
printf("match op=%d i=%d ",op,i);
#endif
if( !(i=optab[op][i]) )
return(0);
skp = codeskels[i];
#ifndef NODEBUG
if( mflag )
printf("codeskels[%d]=%o\n",i,skp);
#endif
#ifndef NODEBUG
if(mflag) {
printf("match LEFT ");
puttsu(ltp);
if(bop) {
printf(" RIGHT ");
puttsu(rtp);
}
putchar('\n');
}
#endif
for( ; skp->sk_left != 0; skp++ ) {
#ifndef NODEBUG
if( mflag > 1 )
printf("sk_left=%x sk_right=%x\n",skp->sk_left,skp->sk_right);
#endif
if( !(skelmatch(ltp,skp->sk_left)) )
continue;
if( bop && !(skelmatch(rtp,skp->sk_right)) )
continue;
#ifndef NODEBUG
if( mflag )
printf("match found skp=%o left=%x right=%x\n",skp,
skp->sk_left,skp->sk_right);
#endif
return(skp);
}
return(0);
}
/* skelmatch - sub-tree type matching for match*/
/* This checks a subtree for type compatability in match.*/
skelmatch(tp,skinfo) /* returns 1 if matched, else 0*/
struct tnode *tp; /* pointer to expression tree*/
int skinfo;
{
register int type, unsignf, const, stype;
if( tp->t_su > skinfo || ((skinfo&T_INDR) && tp->t_op != INDR) )
return(0);
stype = SK_TYPE(skinfo);
type = tp->t_type;
if( function(type) )
type = btype(type);
if( unsignf = unsign(type) )
type = basetype(type);
const = 0;
switch( tp->t_op ) {
case CFLOAT: /* [vlh] 3.4 */
case CLONG:
if( tp->t_su > SU_CONST )
break;
case CINT:
const++;
break;
}
switch( stype ) {
case T_CHAR:
return( type == CHAR );
case T_ANY: /*either int or char*/
if( type == CHAR )
return(1);
case T_INT:
return( type == INT || const );
case T_UNSN:
return( unsignf );
case T_LONG:
return( longorptr(type) );
case T_FLOAT:
return( isfloat(type) );
default:
error("skelmatch type: %x",stype);
return(0);
}
}

View File

@@ -0,0 +1,526 @@
1File: SMATCH.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 /* Code Skeleton expansion and matching */
9
10 #include "cgen.h"
11 #include "cskel.h"
12 #define SK_TYPE(x) (x&017)
13
14 /* expand - code skeleton expansion*/
15 /* Handles the expansion of code skeleton macros.*/
16 expand(tp,cookie,freg,skp) /* returns register result is in*/
17 struct tnode *tp; /* pointer to expression tree*/
18 int cookie; /* goal of expression tree*/
19 int freg; /* register to leave results in*/
20 struct skeleton *skp; /* pointer to code skeleton*/
21 {
22 register int op, nreg, reg;
23 register int c;
24 register int extf, i2f;
25 register struct tnode *ltp, *rtp;
26 register char *p;
27 register int i, inaddreg, sreg, flag, subtrees, scookie;
28 register char *macro;
29
30 #ifndef NODEBUG
31 if( eflag )
32 printf("expand op=%d left=%x right=%x skp=%o\n",tp->t_op,
33 skp->sk_left,skp->sk_right,skp);
34 #endif
35 if( ((op=tp->t_op) >= MULT && op <= XOR) || tp->t_type == CHAR )
36 freg = dreg(freg);
37 macro = skp->sk_def;
38 extf = 0;
39 i2f = 0;
40 rtp = ltp = tp->t_left;
41 subtrees = 1;
42 if( binop(op) ) {
43 subtrees++;
44 rtp = tp->t_right;
45 if( (longorptr(tp->t_type)) && (op == DIV || op == MOD ||
46 (op != MULT && (isdreg(freg)) &&
47 !(longorptr(ltp->t_type)) && !(longorptr(rtp->t_type)))) )
48 extf++;
49 switch( op ) {
50
51 case RSH:
52 case LSH:
53 case EQLSH:
54 case EQRSH:
55 if( unsign(ltp->t_type) )
56 i2f++;
57 break;
58
59 case MULT:
1File: SMATCH.C Page 2
60 case EQMULT:
61 case DIV:
62 case MOD:
63 case EQDIV:
64 case EQMOD:
65 if( unsign(ltp->t_type) || unsign(rtp->t_type) )
66 i2f++;
67 break;
68 }
69 }
70 nreg = freg + 1;
71 while( c = *macro++ ) {
72 c =& 0xff;
73 switch( c ) {
74
75 default:
76 putchar(c);
77 break;
78
79 case POP:
80 stacksize--;
81 printf("(sp)+");
82 break;
83
84 case POP4:
85 stacksize--;
86 popstack(4);
87 break;
88
89 case POP8:
90 stacksize =- 2;
91 popstack(8);
92 break;
93
94 case PSH:
95 if( cookie == FORSP ) /*don't affect sp*/
96 printf("(sp)");
97 else
98 printf("-(sp)");
99 stacksize++;
100 break;
101
102 case MOV:
103 case MOVL:
104 case JSR:
105 case CLR:
106 case CLRL:
107 case EXTW:
108 case EXTL:
109 case LEA:
110 case STK:
111 printf("%s",strtab[c-128]);
112 break;
113
114 case OPCALL:
115 if( isfloat(tp->t_type) || isfloat(ltp->t_type) ) {
116 switch( op ) {
117
118 case ADD:
1File: SMATCH.C Page 3
119 case EQADD:
120 printf("_fpadd");
121 break;
122
123 case SUB:
124 case EQSUB:
125 printf("_fpsub");
126 break;
127
128 case MULT:
129 case EQMULT:
130 printf("_fpmult");
131 break;
132
133 case DIV:
134 case EQDIV:
135 printf("_fpdiv");
136 break;
137
138 case UMINUS:
139 case EQNEG:
140 printf("_fpneg");
141 break;
142
143 case FLOAT2L:
144 case FLOAT2I:
145 printf("_fpftol");
146 break;
147
148 case LONG2F:
149 case INT2F:
150 printf("_fpltof");
151 break;
152
153 case EQUALS:
154 case NEQUALS:
155 case GREAT:
156 case GREATEQ:
157 case LESS:
158 case LESSEQ:
159 printf("_fpcmp");
160 break;
161
162 default:
163 error("invalid floating op %d\n",op);
164 break;
165 }
166 }
167 else {
168 switch( op ) {
169
170 case MULT:
171 case LMULT:
172 printf("lmul");
173 break;
174
175 case DIV:
176 case LDIV:
177 printf("ldiv");
1File: SMATCH.C Page 4
178 break;
179
180 case MOD:
181 case LMOD:
182 printf("lrem");
183 break;
184
185 default:
186 error("opcall bad op %d",op);
187 break;
188 }
189 }
190 break;
191
192 case TLEFT:
193 outtype( leafop(op) ? tp->t_type : ltp->t_type );
194 break;
195
196 case TLEFTL:
197 outatype( leafop(op) ? tp->t_type : ltp->t_type );
198 break;
199
200 case TEITHER:
201 if( longorptr(rtp->t_type) || longorptr(ltp->t_type) )
202 outtype(LONG);
203 break;
204
205 case TRIGHT:
206 outtype(rtp->t_type);
207 break;
208
209 case OP:
210 case AOP:
211 if( c == AOP || i2f )
212 i = optab[op][1];
213 else
214 i = optab[op][0];
215 printf(mnemonics[i]);
216 break;
217
218 case LADDR:
219 case RADDR:
220 p = (c==RADDR?rtp:ltp);
221 outaexpr(p,IMMED);
222 break;
223
224 case CR:
225 outcreg(freg);
226 break;
227
228 case NR:
229 outcreg(nreg);
230 break;
231
232 case CAR:
233 outcreg(areg(freg));
234 break;
235
236 case NAR:
1File: SMATCH.C Page 5
237 outcreg(areg(nreg));
238 break;
239
240 case EXL:
241 outextend(ltp,LONG,freg);
242 break;
243
244 case EXRL:
245 case EXRLN:
246 outextend(rtp,ltp->t_type,c==EXRL?freg:nreg);
247 break;
248
249 case EXLR:
250 case EXLRN:
251 outextend(ltp,rtp->t_type,c==EXLR?freg:nreg);
252 break;
253
254 case LEFT:
255 case RIGHT:
256 subtrees--;
257 case TREE:
258 p = (c==LEFT?ltp:c==RIGHT?rtp:tp);
259 flag = *macro++;
260 scookie = FORREG;
261 if( flag & S_STACK ) {
262 if( cookie == FORSP )
263 scookie = FORSP;
264 else
265 scookie = FORSTACK;
266 }
267 else if( flag & S_FORCC )
268 scookie = FORCC;
269 if( flag & S_NEXT )
270 reg = nreg;
271 else
272 reg = freg;
273 if( flag & S_INDR ) {
274 if( p->t_op != INDR )
275 error("code skeleton error: %d\n",op);
276 p = p->t_left; /*skip INDR*/
277 if( coffset(p) ) {
278 p = p->t_left;
279 if( longorptr(p->t_type) == 0 && (flag&S_STACK) != 0 )
280 p = tnalloc(INT2L,LONG,0,0,p);
281 }
282 reg = areg(reg);
283 }
284 sreg = codegen(p,scookie,reg); /*code for subtree*/
285 if( scookie == FORREG ) {
286 if( flag & S_INDR ) {
287 if( isdreg(sreg) )
288 outmovr(sreg,areg(reg),p);
289 }
290 else if( flag & S_NEXT )
291 nreg = sreg;
292 else if( sreg != reg ) {
293 /*
294 * result was not in expected register, if remaining sub-tree can be
295 * compiled using the remaining registers, update current and next
1File: SMATCH.C Page 6
296 * registers, saving us the trouble of moving the register.
297 */
298 if( c == TREE || ((isdreg(sreg)) && subtrees > 0 &&
299 ((c == LEFT &&
300 sucomp(rtp,sreg,0) <= skp->sk_right &&
301 sucomp(rtp,sreg,1) <= SU_ANY) ||
302 ( c == RIGHT &&
303 sucomp(ltp,sreg,0) <= skp->sk_left &&
304 sucomp(ltp,sreg,1) <= SU_ANY))) ) {
305 freg = dreg(sreg);
306 nreg = freg + 1;
307 }
308 else
309 outmovr(sreg,dreg(freg),p);
310 }
311 }
312 break;
313
314 case LOFFSET:
315 case ROFFSET:
316 p = (c==LOFFSET) ? ltp->t_left : rtp->t_left;
317 if((p=coffset(p)) != 0 && (p->t_op != CINT || p->t_value != 0))
318 outaexpr(p,NOTIMMED);
319 break;
320
321 case MODSWAP:
322 switch( op ) {
323
324 case MOD:
325 case EQMOD:
326 case LMOD:
327 case LEQMOD:
328 outswap(freg);
329 }
330 break;
331
332 }
333 }
334 if( extf && cookie == FORREG && (isdreg(freg)) ) {
335 if( unsign(ltp->t_type) || unsign(rtp->t_type) )
336 outuext(freg);
337 else
338 outext(freg);
339 }
340 #ifndef NODEBUG
341 if( eflag )
342 printf("ending expand skp=%o\n",skp);
343 #endif
344 return(freg);
345 }
346
347 /*
348 * match - try to match expression tree with code skeleton
349 * Given the expression tree, tries to match the given tree with
350 * the appropriate code skeleton. The code skeleton list is
351 * gotten from the root operator and the cookie value. The code
352 * skeleton list is then searched, checking the Sethy-Ullman numbers
353 * of the sub-trees against the Sethy-Ullman numbers in the code
354 * skeleton list. If the Sethy-Ullman numbers are OK, then the
1File: SMATCH.C Page 7
355 * left and right sub-trees are checked for compatability, e.g.
356 * integer pointers, etc. If a match is found, the code skeleton
357 * list pointer is returned.
358 */
359 char *match(tp,cookie,reg) /* returns ptr to code skeleton*/
360 /* or 0 if no skeleton*/
361 struct tnode *tp; /* pointer to tree*/
362 int cookie; /* goal for code expansion*/
363 int reg; /* register to use*/
364 {
365 register struct skeleton *skp;
366 register int op, bop, opndx;
367 int i;
368 register struct tnode *ltp, *rtp;
369
370 #ifndef NODEBUG
371 if( mflag )
372 printf("match op=%d cookie=%d reg=%d\n",tp->t_op,cookie,reg);
373 #endif
374 if( (op=tp->t_op) >= LCGENOP )
375 return(0);
376 if( leafop(op) )
377 ltp = tp;
378 else
379 ltp = tp->t_left;
380 if( (bop=binop(op)) ) {
381 rtp = tp->t_right;
382 if( convop(ltp->t_op) ) {
383 if( op != LSH && notconvop(rtp->t_op) ) {
384 if( !(unsign(ltp->t_left->t_type)) || op == ASSIGN ) {
385 tp->t_left = ltp->t_left;
386 if( (skp=match(tp,cookie,reg)) != 0 )
387 return(skp);
388 tp->t_left = ltp;
389 }
390 }
391 }
392 else if( convop(rtp->t_op) ) {
393 if( !(unsign(rtp->t_left->t_type)) || op == ASSIGN ) {
394 tp->t_right = rtp->t_left;
395 if( (skp=match(tp,cookie,reg)) != 0 )
396 return(skp);
397 tp->t_right = rtp;
398 }
399 }
400 }
401 switch( cookie ) {
402
403 case FORCC:
404 i = 3;
405 break;
406
407 case FOREFF:
408 i = 2;
409 break;
410
411 case FORSTACK:
412 case FORSP:
413 i = 4;
1File: SMATCH.C Page 8
414 break;
415
416 case FORREG:
417 i = 5;
418 break;
419
420 default:
421 error("match cookie=%d\n",cookie);
422 return(0);
423 }
424 #ifndef NODEBUG
425 if( mflag )
426 printf("match op=%d i=%d ",op,i);
427 #endif
428 if( !(i=optab[op][i]) )
429 return(0);
430 skp = codeskels[i];
431 #ifndef NODEBUG
432 if( mflag )
433 printf("codeskels[%d]=%o\n",i,skp);
434 #endif
435 #ifndef NODEBUG
436 if(mflag) {
437 printf("match LEFT ");
438 puttsu(ltp);
439 if(bop) {
440 printf(" RIGHT ");
441 puttsu(rtp);
442 }
443 putchar('\n');
444 }
445 #endif
446 for( ; skp->sk_left != 0; skp++ ) {
447 #ifndef NODEBUG
448 if( mflag > 1 )
449 printf("sk_left=%x sk_right=%x\n",skp->sk_left,skp->sk_right);
450 #endif
451 if( !(skelmatch(ltp,skp->sk_left)) )
452 continue;
453 if( bop && !(skelmatch(rtp,skp->sk_right)) )
454 continue;
455 #ifndef NODEBUG
456 if( mflag )
457 printf("match found skp=%o left=%x right=%x\n",skp,
458 skp->sk_left,skp->sk_right);
459 #endif
460 return(skp);
461 }
462 return(0);
463 }
464
465 /* skelmatch - sub-tree type matching for match*/
466 /* This checks a subtree for type compatability in match.*/
467 skelmatch(tp,skinfo) /* returns 1 if matched, else 0*/
468 struct tnode *tp; /* pointer to expression tree*/
469 int skinfo;
470 {
471 register int type, unsignf, const, stype;
472
1File: SMATCH.C Page 9
473 if( tp->t_su > skinfo || ((skinfo&T_INDR) && tp->t_op != INDR) )
474 return(0);
475 stype = SK_TYPE(skinfo);
476 type = tp->t_type;
477 if( function(type) )
478 type = btype(type);
479 if( unsignf = unsign(type) )
480 type = basetype(type);
481 const = 0;
482 switch( tp->t_op ) {
483
484 case CFLOAT: /* [vlh] 3.4 */
485 case CLONG:
486 if( tp->t_su > SU_CONST )
487 break;
488 case CINT:
489 const++;
490 break;
491 }
492 switch( stype ) {
493
494 case T_CHAR:
495 return( type == CHAR );
496
497 case T_ANY: /*either int or char*/
498 if( type == CHAR )
499 return(1);
500 case T_INT:
501 return( type == INT || const );
502
503 case T_UNSN:
504 return( unsignf );
505
506 case T_LONG:
507 return( longorptr(type) );
508
509 case T_FLOAT:
510 return( isfloat(type) );
511
512 default:
513 error("skelmatch type: %x",stype);
514 return(0);
515 }
516 }
517

View File

@@ -0,0 +1,110 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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 CFLOAT:
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 LMOD:
case LMULT:
case CALL:
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);
if( isfloat(tp->t_type) )
su = SU_VHARD;
break;
}
if( flag )
tp->t_su = su;
return(su);
}

View File

@@ -0,0 +1,112 @@
1File: SUCOMP.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9 #include "cskel.h"
10
11 /* sucomp - Sethy-Ullman expression complexity measure computation*/
12 /* This is a heuristic computation of the Sethy-Ullman numbers*/
13 /* for expressions. This gives an approximation of the complexity*/
14 /* of the expression. The code generation scheme works best if*/
15 /* the most complex expressions are done first.*/
16 sucomp(tp,nregs,flag) /* returns - none*/
17 struct tnode *tp; /* pointer to tree*/
18 int nregs; /* number of registers left*/
19 int flag; /* 1=>set values in tree, 0=>return*/
20 {
21 register int su, sur, op, i;
22 register struct tnode *ltp, *rtp;
23
24 nregs = dreg(nregs);
25 if( binop(op=tp->t_op) ) {
26 ltp = tp->t_left;
27 rtp = tp->t_right;
28 }
29 else if( unaryop(op) )
30 ltp = tp->t_left;
31 switch( op ) {
32
33 case CLONG:
34 if( tp->t_lvalue >= 0x8000L || tp->t_lvalue <= 0xffff8000L ) {
35 su = SU_ADDR;
36 break;
37 }
38 i = tp->t_lvalue;
39 case CINT:
40 if( op == CINT )
41 i = tp->t_value;
42 if( i == 0 )
43 su = SU_ZERO;
44 else if( i == 1 )
45 su = SU_ONE;
46 else if( i >= 1 && i <= QUICKVAL )
47 su = SU_SMALL;
48 else if( i >= -128 && i <= 127 )
49 su = SU_QUICK;
50 else
51 su = SU_CONST;
52 break;
53
54 case COMMA:
55 su = max(sucomp(rtp,nregs,flag),sucomp(ltp,nregs,flag));
56 su = max(su,SU_EASY);
57 break;
58
59 case ADDR:
1File: SUCOMP.C Page 2
60 su = sucomp(ltp,nregs,flag);
61 break;
62
63 case CFLOAT:
64 case DCLONG:
65 case AUTOINC:
66 case AUTODEC:
67 su = SU_ADDR;
68 break;
69
70 case SYMBOL:
71 if( tp->t_sc != REGISTER )
72 su = SU_ADDR;
73 else if( isdreg(tp->t_reg) )
74 su = SU_REG;
75 else
76 su = SU_AREG;
77 break;
78
79 case LDIV:
80 case LMOD:
81 case LMULT:
82 case CALL:
83 sucomp(rtp,nregs,flag);
84 case NACALL:
85 sucomp(ltp,nregs,flag);
86 su = SU_VHARD; /*very hard*/
87 break;
88
89 default:
90 su = sucomp(ltp,nregs,flag);
91 if( binop(op) ) {
92 if( su <= SU_ADDR )
93 su = max(su,sucomp(rtp,nregs,flag));
94 else {
95 sur = sucomp(rtp,nregs+1,flag);
96 if( sur > SU_ADDR && nregs > HICREG )
97 su = max(su,SU_HARD);
98 }
99 su = max(SU_EASY,su);
100 }
101 else if( su <= SU_XREG )
102 su = max(SU_EASY,su);
103 if( isfloat(tp->t_type) )
104 su = SU_VHARD;
105 break;
106 }
107 if( flag )
108 tp->t_su = su;
109 return(su);
110 }

View File

@@ -0,0 +1,118 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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, /*EQNOT*/
TRMPRI, /*EQNEG*/
TRMPRI|OPBIN, /*DOCAST*/
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2I [vlh] 3.4*/
UNOPRI|OPRAS, /*TOCHAR [vlh] 4.0*/
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|OPTERM, /*CFLOAT [vlh] 3.4*/
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,121 @@
1File: TABL.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9 #define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
10
11 /*info on operators:*/
12 /*000077-- OPPRI - priority*/
13 /*000100-- OPBIN - binary operator*/
14 /*000200-- OPLVAL - left operand must be lvalue*/
15 /*000400-- OPREL - relational operator*/
16 /*001000-- OPASSIGN - assignment operator*/
17 /*002000-- OPLWORD - int required on left*/
18 /*004000-- OPRWORD - int required on right*/
19 /*010000-- OPCOM commutative*/
20 /*020000-- OPRAS - right associative*/
21 /*040000-- OPTERM - termination node*/
22 /*100000 - OPCONVS - conversion operator*/
23 int opinfo[] {
24 TRMPRI, /*EOF*/
25 ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
26 ADDPRI|OPBIN, /*SUB - expr - expr*/
27 MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
28 MULPRI|OPBIN, /*DIV - expr / expr*/
29 MULPRI|OPBIN, /*MOD - expr % expr*/
30 SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
31 SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
32 ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
33 ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
34 ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
35 UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
36 UNOPRI|OPRAS, /*UMINUS - - expr*/
37 UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
38 UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
39 UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
40 UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
41 UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
42 ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
43 ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
44 ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
45 ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
46 ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
47 ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
48 ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
49 ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
50 ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
51 ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
52 ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
53 TRMPRI, /*FJSR - generate function jsr*/
54 EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
55 EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
56 RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
57 RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
58 RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
59 RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
1File: TABL.C Page 2
60 TRMPRI|OPCONVS, /*INT2L*/
61 TRMPRI|OPCONVS, /*LONG2I*/
62 TRMPRI|OPBIN, /*BTST*/
63 TRMPRI, /*LOAD*/
64 TRMPRI|OPBIN, /*LMULT*/
65 TRMPRI|OPBIN, /*LDIV*/
66 TRMPRI|OPBIN, /*LMOD*/
67 TRMPRI|OPBIN, /*LEQMULT*/
68 TRMPRI|OPBIN, /*LEQDIV*/
69 TRMPRI|OPBIN, /*LEQMOD*/
70 TRMPRI|ASGOP, /*EQADDR*/
71 TRMPRI, /*EQNOT*/
72 TRMPRI, /*EQNEG*/
73 TRMPRI|OPBIN, /*DOCAST*/
74 ASGPRI|ASGOP, /*STASSIGN [vlh]*/
75 TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
76 TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
77 TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
78 TRMPRI|OPCONVS, /*FLOAT2I [vlh] 3.4*/
79 UNOPRI|OPRAS, /*TOCHAR [vlh] 4.0*/
80 TRMPRI, /*unused - 56*/
81 TRMPRI, /*unused - 57*/
82 TRMPRI, /*unused - 58*/
83 TRMPRI, /*unused - 59*/
84 UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
85 UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
86 LNDPRI|OPBIN, /*LAND - expr && expr*/
87 LORPRI|OPBIN, /*LOR - expr || expr*/
88 QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
89 QMKPRI|OPRAS|OPBIN, /*COLON*/
90 COMPRI|OPBIN, /*COMMA*/
91 TRMPRI|OPTERM, /*CINT*/
92 TRMPRI|OPTERM, /*CLONG*/
93 TRMPRI|OPTERM, /*SYMBOL*/
94 TRMPRI|OPTERM, /*AUTOINC*/
95 TRMPRI|OPTERM, /*AUTODEC*/
96 LPNPRI|OPBIN, /*CALL - call with arguments*/
97 LPNPRI, /*NACALL - no argument call*/
98 TRMPRI, /*BFIELD - field selection*/
99 TRMPRI, /*CONDBR*/
100 TRMPRI, /*INIT*/
101 TRMPRI, /*LOADREG*/
102 TRMPRI|OPTERM, /*DCLONG - divide const long*/
103 TRMPRI|OPTERM, /*CFLOAT [vlh] 3.4*/
104 UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
105 TRMPRI, /*SEMI*/
106 TRMPRI, /*LCURBR - {*/
107 TRMPRI, /*RCURBR - }*/
108 LPNPRI, /*LBRACK - [*/
109 RPNPRI, /*RBRACK - ]*/
110 LPNPRI, /*LPAREN - )*/
111 RPNPRI, /*RPAREN - )*/
112 TRMPRI|OPTERM, /*STRING*/
113 TRMPRI, /*RESWORD*/
114 LPNPRI|OPBIN, /*APTR - expr -> symbol*/
115 LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
116 UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
117 LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
118 };
1File: TABL.C Page 3

View File

@@ -0,0 +1,21 @@
e:vax CANON.C s
e:vax CODEGEN.C s
e:vax CSKELS.C s
e:vax INTERF.C s
e:vax MAIN.C s
e:vax OPTAB.C s
e:vax PUTEXPR.C s
e:vax SMATCH.C s
e:vax SUCOMP.C s
e:vax TABL.C s
e:vax UTIL.C s
e:vax VERSION.C s
e:vax CGEN.H s
e:vax CSKEL.H s
e:vax ICODE.H s
e:vax MACHINE.68K s
e:vax LINK.SUB s
e:vax MAKE.SUB s
e:vax MACHINE.H s
e:vax SEND13.SUB s
e:vax up13.sub s

View File

@@ -0,0 +1,357 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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 CFLOAT: /*[vlh] 3.4 */
return(fpcnalloc(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:
case CFLOAT: /*[vlh] 3.4 */
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 CFINDR: /* [vlh] 3.4 */
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:
case CFINDR: /* [vlh] 3.4 */
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( isfloat(type) )
printf(".l");
else 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) || isfloat(type) )
printf(".l");
}
/* 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)) && (longorptr(type)) ) {
if( unsign(tp->t_type) )
outuext(reg);
else
outext(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);
}
/* 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');
}
outdbra(reg,lab)
int reg;
int lab;
{
printf("dbra R%d,L%d\n",reg,lab);
}
/* 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);
}
/*popstack - clear off the stack after a call if necessary */
popstack(nb)
{
if (nb > 0 && nb <= 8)
printf("addq.l #%d,sp\n",nb);
else if (nb > 0)
printf("adda.l #%d,sp\n",nb);
}

View File

@@ -0,0 +1,364 @@
1File: UTIL.C Page 1
1 /*
2 Copyright 1982
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "cgen.h"
9 #include "cskel.h"
10
11 /* xnalloc - allocate address-indexed node*/
12 char *xnalloc(type,ar,off,xr,xt) /* returns ptr to node alloced*/
13 int type; /* data type*/
14 int ar; /* address register*/
15 int off; /* 8-bit offset*/
16 int xr; /* index register*/
17 int xt; /* index register type*/
18 {
19 register struct indexnode *xp;
20
21 xp = talloc(sizeof(*xp));
22 xp->t_op = SYMBOL;
23 xp->t_type = type;
24 xp->t_sc = INDEXED;
25 xp->t_reg = ar;
26 xp->t_su = SU_ADDR;
27 xp->t_offset = off;
28 xp->t_xreg = xr;
29 xp->t_xtype = xt;
30 return(xp);
31 }
32
33 /* tcopy - expression tree copy*/
34 char *tcopy(tp) /* returns ptr to copied tree*/
35 struct tnode *tp;
36 {
37 register char *p;
38
39 switch( tp->t_op ) {
40
41 case SYMBOL:
42 if( tp->t_sc == EXTERNAL || tp->t_sc == EXTOFF )
43 p = cenalloc(tp->t_type,tp->t_sc,tp->t_symbol);
44 else {
45 p = snalloc(tp->t_type,tp->t_sc,tp->t_offset,0,0);
46 p->t_label = tp->t_label;
47 }
48 p->t_offset = tp->t_offset;
49 p->t_reg = tp->t_reg;
50 return(p);
51
52 case CINT:
53 return(cnalloc(tp->t_type,tp->t_value));
54
55 case CLONG:
56 return(lcnalloc(tp->t_type,tp->t_lvalue));
57
58 case CFLOAT: /*[vlh] 3.4 */
59 return(fpcnalloc(tp->t_type,tp->t_lvalue));
1File: UTIL.C Page 2
60
61 case DCLONG:
62 p = lcnalloc(tp->t_type,tp->t_lvalue);
63 p->t_op = DCLONG;
64 return(p);
65
66 default:
67 if( binop(tp->t_op) )
68 return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
69 tcopy(tp->t_right)));
70 if( unaryop(tp->t_op) )
71 return(tnalloc(tp->t_op,tp->t_type,0,0,tcopy(tp->t_left),
72 null));
73 error("tcopy op=%d",tp->t_op);
74 return(tp);
75 }
76 }
77
78 /* outaexpr - output address expression*/
79 outaexpr(tp,flags) /* returns - none*/
80 struct tnode *tp; /* pointer to tree*/
81 int flags; /* flags (IMMED,LOFFSET,...)*/
82 {
83 register int off, reg, lab;
84 long l;
85
86 if( tp->t_op == ADDR ) {
87 tp = tp->t_left;
88 putchar('#');
89 }
90 off = tp->t_offset;
91 reg = tp->t_reg;
92 lab = tp->t_label;
93 switch( tp->t_op ) {
94
95 case AUTOINC:
96 printf("(R%d)+",reg);
97 break;
98
99 case AUTODEC:
100 printf("-(R%d)",reg);
101 break;
102
103 case CINT:
104 if( flags & IMMED )
105 putchar('#');
106 printf("%d",tp->t_value);
107 break;
108
109 case DCLONG:
110 case CLONG:
111 case CFLOAT: /*[vlh] 3.4 */
112 if( flags & IMMED )
113 putchar('#');
114 outlval(tp->t_lvalue);
115 break;
116
117 case SYMBOL:
118 if( off ) {
1File: UTIL.C Page 3
119 switch( tp->t_sc ) {
120
121 default:
122 printf("%d+",off);
123 break;
124
125 case REGOFF:
126 printf("%d",off);
127 case CINDR:
128 case CLINDR:
129 case CFINDR: /* [vlh] 3.4 */
130 case INDEXED:
131 break;
132
133 case REGISTER:
134 error("invalid register expression");
135 break;
136 }
137 }
138 switch( tp->t_sc ) {
139
140 case REGISTER:
141 printf("R%d",reg);
142 break;
143
144 case REGOFF:
145 printf("(R%d)",reg);
146 break;
147
148 case EXTERNAL:
149 printf("_%.8s",tp->t_symbol);
150 break;
151
152 case EXTOFF:
153 printf("_%.8s(R%d)",tp->t_symbol,reg);
154 break;
155
156 case STATIC:
157 printf("L%d",lab);
158 break;
159
160 case STATOFF:
161 printf("L%d(R%d)",lab,reg);
162 break;
163
164 case INDEXED:
165 printf("%d(R%d,R%d",off,reg,tp->t_xreg);
166 outatype(tp->t_xtype);
167 putchar(')');
168 break;
169
170 case CINDR:
171 printf("%d",off);
172 break;
173 /*
174 * the following will work on: PDP-11, 68000, IBM-360, VAX, etc.
175 * it will not work on word machines or on machines where either
176 * longs two ints or two shorts.
177 */
1File: UTIL.C Page 4
178 case CLINDR:
179 case CFINDR: /* [vlh] 3.4 */
180 l.hiword = tp->t_offset;
181 l.loword = tp->t_ssp;
182 outlval(l);
183 break;
184
185 default:
186 error("invalid storage class %d\n",tp->t_sc);
187 break;
188 }
189 break;
190
191 default:
192 error("invalid operator %d\n",tp->t_op);
193 break;
194 }
195 }
196
197 /* outlval - output long value*/
198 /* This is a big pain because the PDP-11 doesn't do long divides*/
199 /* in hardware.*/
200 outlval(lval)
201 long lval;
202 {
203 char digs[8];
204 register int i, c;
205
206 i = 0;
207 do {
208 digs[i++] = lval & 0xf;
209 lval =>> 4;
210 lval =& 0xfffffff;
211 } while ( lval );
212 putchar('$');
213 while( --i >= 0 ) {
214 c = digs[i];
215 putchar(c>=10?c+('a'-10):c+'0');
216 }
217 }
218
219 /* outtype - output 68000 type (null, .b, .l) depending on data type*/
220 outtype(type)
221 int type;
222 {
223 if( isfloat(type) )
224 printf(".l");
225 else if( longorptr(type) )
226 printf(".l");
227 else if( type == CHAR )
228 printf(".b");
229 }
230
231 /* outatype - output address type (.l or null) depending on data type*/
232 outatype(type)
233 int type;
234 {
235 if( longorptr(type) || isfloat(type) )
236 printf(".l");
1File: UTIL.C Page 5
237 }
238
239 /* outextend - output register extension to long depending on type*/
240 outextend(tp,type,reg) /* returns - none*/
241 struct tnode *tp; /* tree to convert from*/
242 int type; /* type to convert to*/
243 int reg; /* register to convert*/
244 {
245 if( (isdreg(reg)) && !(longorptr(tp->t_type)) && (longorptr(type)) ) {
246 if( unsign(tp->t_type) )
247 outuext(reg);
248 else
249 outext(reg);
250 }
251 }
252
253 /* outrr - output register to register instruction*/
254 outrr(ins,r1,r2,tp)
255 char *ins;
256 int r1;
257 int r2;
258 struct tnode *tp;
259 {
260 printf("%s",ins);
261 if( isareg(r1) || isareg(r2) )
262 outatype(tp->t_type);
263 else
264 outtype(tp->t_type);
265 printf(" R%d,R%d\n",r1,r2);
266 }
267
268 /* outmovr - output "move[type] R1,R2" instruction*/
269 outmovr(r1,r2,tp)
270 int r1;
271 int r2;
272 struct tnode *tp;
273 {
274 if( r1 != r2 )
275 outrr("move",r1,r2,tp);
276 }
277
278 /* outcmpm - output "cmpm[type] (R1)+,(R2)+"*/
279 outcmpm(tp)
280 struct tnode *tp;
281 {
282 printf("cmpm");
283 outtype(tp->t_left->t_type);
284 printf(" (R%d)+,(R%d)+\n",tp->t_left->t_reg,tp->t_right->t_reg);
285 }
286
287 /* outcreg - output reference to compiler temp register*/
288 outcreg(reg)
289 int reg;
290 {
291 if( (dreg(reg)) > HICREG )
292 error("expression too complex");
293 printf("R%d",reg);
294 }
295
1File: UTIL.C Page 6
296 /* outcmp0 - output a compare with 0, special for address register*/
297 outcmp0(reg,tp)
298 int reg;
299 struct tnode *tp;
300 {
301 if( isareg(reg) ) {
302 printf("cmp");
303 outatype(tp->t_type);
304 printf(" #0,R%d\n",reg);
305 }
306 else {
307 printf("tst");
308 outtype(tp->t_type);
309 printf(" R%d\n",reg);
310 }
311 }
312
313 /* outrpush - output "move[type] R1,[-](sp)"*/
314 outrpush(reg,tp,pflag)
315 int reg;
316 struct tnode *tp;
317 int pflag;
318 {
319 printf("move");
320 outatype(tp->t_type);
321 printf(" R%d,%c(sp)\n",reg,pflag?'-':'\0');
322 }
323
324 outdbra(reg,lab)
325 int reg;
326 int lab;
327 {
328 printf("dbra R%d,L%d\n",reg,lab);
329 }
330
331 /* cenalloc - code generator external node allocation*/
332 /* This may be coalesced into enalloc in parser.*/
333 char *cenalloc(type,sc,sym) /* returns ptr to node alloced*/
334 int type; /* type of symbol*/
335 int sc; /* storage class*/
336 char *sym; /* symbol name*/
337 {
338 register struct extnode *ep;
339
340 ep = talloc(sizeof(*ep));
341 ep->t_op = SYMBOL;
342 ep->t_type = type;
343 ep->t_sc = sc;
344 ep->t_su = 0;
345 ep->t_offset = 0;
346 symcopy(sym,ep->t_symbol);
347 return(ep);
348 }
349
350 /*popstack - clear off the stack after a call if necessary */
351 popstack(nb)
352 {
353 if (nb > 0 && nb <= 8)
354 printf("addq.l #%d,sp\n",nb);
1File: UTIL.C Page 7
355 else if (nb > 0)
356 printf("adda.l #%d,sp\n",nb);
357 }

View File

@@ -0,0 +1 @@
char *compiled "@(#) code generator - Fri Mar 18 12:02 1983";

View File

@@ -0,0 +1,2 @@
1File: VERSION.C Page 1
1 char *compiled "@(#) code generator - Fri Mar 18 12:02 1983";

View File

@@ -0,0 +1,20 @@
$ cgen
$ set noon
$ !
$ ! C168 make file for VMS
$ !
$ copy machine.vax machine.h
$ pur machine.h
$ cx CANON
$ cx CODEGEN
$ cx CSKELS
$ cx INIT
$ cx INTERF
$ cx MAIN
$ cx OPTAB
$ cx PUTEXPR
$ cx SMATCH
$ cx SUCOMP
$ cx TABL
$ cx UTIL
$ clink canon,codegen,cskels,interf,main,optab,putexpr,smatch,sucomp,tabl,util,init,lib:klib/lib c168

View File

@@ -0,0 +1,28 @@
$ set noon
$ vsend CANON.C
$ vsend CGEN.H
$ vsend CODEGEN.C
$ vsend CSKEL.H
$ vsend CSKELS.C
$ vsend ICODE.H
$ vsend INIT.C
$ vsend INTERF.C
$ vsend LINK.SUB
$ vsend LIST.COM
$ vsend MACHINE.11
$ vsend MACHINE.68K
$ vsend MACHINE.H
$ vsend MACHINE.VAX
$ vsend MAIN.C
$ vsend MAKE.SUB
$ vsend OPTAB.C
$ vsend PUTEXPR.C
$ vsend SEND13.SUB
$ vsend SMATCH.C
$ vsend SUCOMP.C
$ vsend TABL.C
$ vsend UP13.SUB
$ vsend UTIL.C
$ vsend VERSION.C
$ vsend VMAKE.COM
$ vsend done

View File

@@ -0,0 +1,17 @@
$ xer CANON.LIS
$ xer CODEGEN.LIS
$ xer CSKELS.LIS
$ xer INIT.LIS
$ xer INTERF.LIS
$ xer MAIN.LIS
$ xer OPTAB.LIS
$ xer PUTEXPR.LIS
$ xer SMATCH.LIS
$ xer SUCOMP.LIS
$ xer TABL.LIS
$ xer UTIL.LIS
$ xer VERSION.LIS
$ xer CGEN.LST
$ xer CSKEL.LST
$ xer ICODE.LST
$ xer MACHINE.LST

View File

@@ -0,0 +1,22 @@
Directory DRB0:[STEVE.CPM68K.V102.C168]
CANON.LIS;1
CODEGEN.LIS;1
CSKELS.LIS;1
INIT.LIS;1
INTERF.LIS;1
MAIN.LIS;1
OPTAB.LIS;1
PUTEXPR.LIS;1
SMATCH.LIS;1
SUCOMP.LIS;1
TABL.LIS;1
UTIL.LIS;1
VERSION.LIS;1
CGEN.LST;1
CSKEL.LST;1
ICODE.LST;1
MACHINE.LST;1
Total of 17 files.