Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/cc85.c
There are no other files named cc85.c in the archive.
/* cc85.c -- Code generator TOPS-20 (contd) (C) 1981 K. Chen */
#define sd extern
#include "cc.g"
/* ------------------------- */
/* binary operator */
/* ------------------------- */
gbinop(n)
struct NODE *n;
{
int r1, r2, ptr;
ptr = charpointer(n->ntype) ||
charpointer(n->left->ntype) ||
charpointer(n->right->ntype);
if (ptr && n->right->nop == ICONST) {
if (n->right->niconst) r2 = genstmt(n->right);
r1 = genstmt(n->left);
if (!n->right->niconst) return r1;
}
else {
if (n->right->nop == FNCALL) {
r2 = genstmt(n->right); /* do function call first */
r1 = genstmt(n->left);
}
else {
r1 = genstmt(n->left);
r2 = genstmt(n->right);
}
}
if (n->nop == RSHFT) code0(NEG, r2, r2);
return regbin (n, r1, r2, ptr);
}
regbin(n, r1, r2, ptr)
struct NODE *n;
{
int r0, rp, ri, pint;
struct PSEUDO *p, *b, *before(), temp;
if (ptr) {
pint = 0;
if (charpointer(n->left->ntype)) {
if (!charpointer(n->right->ntype)) {
pint = 1; /* pointer OP int */
}
rp = r1;
ri = r2;
}
else {
pint = -1; /* int OP pointer */
rp = r2;
ri = r1;
}
if (pint) {
switch (n->nop) {
case MINUS:
code0(NEG, ri, ri);
/* fall through */
case PLUS:
code0(ADJBP, ri, rp);
}
}
else {
fprintf(stderr,"Pointer/pointer arithmetic!!\n");
}
return ri; /* resultant pointer */
}
if (n->nop == PLUS && optimize) {
if ((p=previous) != NULL && p->preg == r2) {
switch (p->ptype) {
case INDEXED:
if (p->pop == IDENT) {
p->pop = PLUS;
p->preg = r1;
regis[r2] = -1;
return r1;
}
break;
case GADDR:
if (p->pop == IDENT) {
p->pop = PLUS;
p->preg = r1;
regis[r2] = -1;
if ((b = before(p)) != NULL && b->preg == r1 &&
b->ptype == IMMED && b->pop == PLUS) {
b->pop = NOP;
p->poffset = p->poffset + b->pvalue;
}
return r1;
}
break;
}
}
}
if (n->nop == DIV || n->nop == MOD) {
if (regis[r1+1] < 0) {
regis[r1+1] = 1;
}
else {
r0 = getpair();
code0(IDENT, r0, r1); /* copy over */
r1 = r0;
}
code0(n->nop, r1, r2);
if (n->nop == MOD) {
release(r1);
return r1+1;
}
release(r1+1);
return r1;
}
code0(n->nop, r1, r2);
return r1;
}
/* --------------------------- */
/* get real register */
/* --------------------------- */
#define MAXREG 14
getreg()
{
int i, iter;
iter = 0;
while (1) {
for (i = 2; i < MAXREG ; i++) {
if (regis[i] < 0) break;
}
if (i < MAXREG) {
regis[i] = 1;
return i;
}
flushcode ((iter > 6) ? 0 : 16);
if (iter++ > 8) {
if (i == MAXREG) {
fprintf(stderr, "Out of registers.\n");
return 0;
}
regis[i] = 1;
return i;
}
}
}
/* -------------------------------------- */
/* get a pair of real registers */
/* -------------------------------------- */
getpair()
{
int i, iter;
iter = 0;
while (1) {
for (i = 2; i < 15 ; i++) {
if (regis[i] < 0 && regis[i+1] < 0) break;
}
if (i < 12) {
regis[i] = 1;
regis[i+1] = 1;
return i;
}
flushcode(8);
if (iter++ > 8) {
if (i == 15) {
fprintf(stderr, "Out of registers.\n");
return 0;
}
regis[i] = 1;
regis[i+1] = 1;
return i;
}
}
}
/* ------------------------------------- */
/* get mapped register for ac0 */
/* ------------------------------------- */
getzero()
{
int i, z;
z = 0;
if (regis[z] >= 0) {
fprintf(stderr,"Compiler error: AC0 not mapped out!\n");
}
regis[z] = 1;
for (i = 16; i < 32 ; i++) {
if (regis[i] < 0) {
regis[i] = 0;
return regis[z] = i;
}
}
fprintf(stderr, "Out of virtual registers.\n");
return 0;
}
/* -------------------------- */
/* release register */
/* -------------------------- */
release(r)
{
if (r >= 0 && regis[r] >= 0) code5(RELEASE, r);
}
/* ------------------------------------------ */
/* unrelease register if neccessary */
/* ------------------------------------------ */
unrelease(p, r)
struct PSEUDO *p;
{
struct PSEUDO *q;
int n;
n = maxcode;
while (n >= 0) {
q = &codes[n&(MAXCODE-1)];
if (q == p) return 1;
if (q->pop == RELEASE && q->preg == r) {
q->pop = NOP;
return 1;
}
if (q->pop == CODED && q->preg == r) return 0; /* coded already! */
n--;
}
return 1;
}
/* --------------------------------------------------- */
/* return location of one instruction before */
/* --------------------------------------------------- */
struct PSEUDO *before(i)
struct PSEUDO *i;
{
int n, r;
struct PSEUDO *p;
n = maxcode;
while (1) {
n--;
if (n < 0) return NULL;
p = &codes[n&(MAXCODE-1)];
if (p == i) break;
}
while (--n >= 0) {
p = &codes[n&(MAXCODE-1)];
if ((r = p->pop) < 1000 || r == GLABEL) return p;
if (r == CODED) return NULL;
}
return NULL;
}
/* ----------------------------------------------------------- */
/* change a register from a given one to a given one */
/* ----------------------------------------------------------- */
changereg(to,from)
{
struct PSEUDO *p;
int n;
if (from > 15) { /* virtual AC0 */
if (regis[from] == to) return;
code0(IDENT, to, from); /* copy over */
return;
}
if (to > 15) to = 0;
n = maxcode-1;
while (1) {
if (n < 0) return;
p = &codes[n&(MAXCODE-1)];
if (p->pop == RELEASE && p->preg == from) return;
switch (p->ptype) {
case LAB:
case BOTH:
case IMMED:
case GADDR:
case LADDR:
case LOCAL:
case RCONST:
case GLOBAL:
case ONEREG:
case INDEXED:
case MINDEXED:
case BYTEPOINT:
case MINDIRECT:
if (p->preg == from) p->preg = to;
break;
case REGIS:
case INDIRECT:
if (p->pr1 == from) p->pr1 = to;
if (p->pr2 == from) p->pr2 = to;
break;
}
n--;
}
}
getlabel()
{
return ++maxlabel;
}
maklabel(s, n)
char *s;
{
int k;
*s++ = '$';
if (k = n&0700) {
*s++ = (k>>6) + '0';
*s++ = ((n&070)>>3) + '0';
}
else {
if (k = n&070) *s++ = (k>>3) + '0';
}
*s++ = (n&07) + '0';
*s = 0;
return;
}
/* ---------------------------------------- */
/* swap two pseudo code locations */
/* ---------------------------------------- */
swappseudo(a,b)
struct PSEUDO *a, *b;
{
struct PSEUDO temp;
copypseudo(&temp, b);
copypseudo(b, a);
copypseudo(a, &temp);
}
/* ------------------------- */
/* copy pseudocode */
/* ------------------------- */
copypseudo(a,b)
struct PSEUDO *a, *b;
{
a->ptype = b->ptype;
a->pop = b->pop;
a->preg = b->preg;
a->pptr = b->pptr;
a->poffset = b->poffset;
a->pindex = b->pindex;
}
/* ---------------------------------------- */
/* generate code for function end */
/* ---------------------------------------- */
gend()
{
int l;
flushcode(0);
while (maxlit--) { /* output literals */
outc('$');
outnum(literal[maxlit].llabel);
if (FAIL) outc(':');
if (NBYTES == 5) outstr(":\tPOINT\t7,.+1,6");
else outstr(":\tPOINT\t9,.+1,8");
outc('\n');
outc('\t');
asciz(literal[maxlit].lptr);
outc('\n');
}
}