Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/cc82.c
There are no other files named cc82.c in the archive.
/* cc82.c -- Code generator TOPS-20 (contd) (C) 1981 K. Chen */
#define sd extern
#include "cc.g"
/* -------------------------- */
/* return statement */
/* -------------------------- */
greturn(n)
struct NODE *n;
{
int r;
struct PSEUDO *p;
r = -1;
if (n->right != NULL) {
r = genstmt(n->right);
if (n->right->nop == QUERY)
code0(IDENT, 0, r);
else
/* changereg(0, r); */
code0(IDENT, 0, r); /* too many bugs, do not optimize */
release(r);
r = 0;
}
p = previous;
if (p->pop != RETURN || !optimize) {
if (maxauto) code8(ADJSP, SP, -maxauto);
code5(RETURN, SP);
}
return r;
}
/* ------------------------------ */
/* assignment statement */
/* ------------------------------ */
gassign(n)
struct NODE *n;
{
int r0, r1, r2, ptr, opt;
struct NODE *nod;
struct PSEUDO *q;
nod = n->left;
ptr = (nod->nop != IDENT) ? charpointer(nod->left->ntype)
: charpointer(nod->ntype);
if ((ptr && n->nop != ASGN) || (n->nop == ASMOD) || (n->nop == ASDIV) ||
(n->nop == ASLSH) || (n->nop == ASRSH)) {
nod = defnode(N3, ASGN, n->ntype, 0, nod, n);
switch (n->nop) {
case ASMINUS:
n->nop = MINUS;
break;
case ASPLUS:
n->nop = PLUS;
break;
case ASMPLY:
n->nop = MPLY;
break;
case ASAND:
n->nop = AND;
break;
case ASOR:
n->nop = OR;
break;
case ASXOR:
n->nop = XOR;
break;
case ASDIV:
n->nop = DIV;
break;
case ASMOD:
n->nop = MOD;
break;
case ASLSH:
n->nop = LSHFT;
break;
case ASRSH:
n->nop = RSHFT;
break;
default:
fprintf(stderr,"Unimplemented assignment operator.\n");
return 0;
}
return genstmt(nod);
}
ptr = (nod->nop != IDENT) ? charpointer(nod->left->ntype)
: 0;
r1 = genstmt(n->right);
r2 = gaddress(nod);
if (n->nop != ASGN) {
switch (n->nop) {
case ASMINUS:
code0(NEG, r1, r1);
/* fall through */
case ASPLUS:
case ASMPLY:
case ASAND:
case ASOR:
case ASXOR:
code4(n->nop, r1, r2);
release(r2);
return r1;
default:
fprint(stderr, "Assignment %d operator not implemented yet.\n");
}
}
if (ptr)
code0(DPB, r1, r2);
else
gistore(r2, r1);
release(r2);
return r1;
}
/* ------------------------------------------- */
/* indirect fetch through a register */
/* ------------------------------------------- */
regfetch(r, ptr)
{
int q;
q = getreg();
code4(IDENT, q, r); /* only int for now, ptr is chararray flag */
return q;
}
/* ----------------------- */
/* fetch address */
/* ----------------------- */
gaddress(n)
struct NODE *n;
{
int r, p, op, more, offset;
struct SYMBOL *s;
struct NODE *m;
switch (n->nop) {
case PTR:
switch (op = n->left->nop) {
case PINC:
return incdec(n->left, INC, 1, 1);
case PDEC:
return incdec(n->left, DEC, 1, 1);
case INC:
case DEC:
return incdec(n->left, op, 0, 1);
default:
return genstmt(n->left);
}
return r;
case DOT:
case MEMBER:
r = (n->nop == MEMBER) ? genstmt(n->left) : gaddress(n->left);
more = 1;
m = n->right;
while (more) {
switch (m->nop) {
case MEMBER:
case DOT:
offset = m->left->nid->svalue;
if (offset) code1(PLUS, r, offset);
if (m->nop == MEMBER) code4(IDENT, r, r);
m = m->right;
break;
default:
offset = m->nid->svalue;
if (offset) code1(PLUS, r, offset);
more = 0;
}
}
if (chararray(n->right->ntype)) code1(HRL, r, MSBYTE);
return r;
case IDENT:
r = getreg();
s = n->nid;
if (chararray(n->ntype)) {
switch (s->sclass) {
case SAUTO:
code13(IDENT, r, s->svalue-stackoffset+1);
code1(HRL, r, MSBYTE);
break;
case SARG:
code13(IDENT, r, -(s->svalue+stackoffset));
code1(HRL, r, MSBYTE);
break;
default:
code9(IDENT, r, s, MSBYTE);
}
}
else {
switch (s->sclass) {
case SAUTO:
code13(IDENT, r, s->svalue-stackoffset+1);
break;
case SARG:
code13(IDENT, r, -(s->svalue+stackoffset));
break;
default:
code3(IDENT, r, s);
}
}
return r;
}
}
/* ----------------------------------------- */
/* store indirect through register */
/* ----------------------------------------- */
gistore(rd,rs)
{
int q;
if (rd > 15) {
q = getreg();
code0(IDENT, q, rd);
code4(ASGN, rs, q);
release(q);
return;
}
code4(ASGN, rs, rd);
}
/* -------------------------------------- */
/* fetch constant into register */
/* -------------------------------------- */
gconst(n)
struct NODE *n;
{
int r, l;
r = getreg();
if (n->nop == SCONST) {
l = getlabel();
literal[maxlit].llabel = l;
literal[maxlit++].lptr = n->nsconst;
code6(IDENT, r, l);
return r;
}
code1(IDENT, r, n->niconst);
return r;
}
/* -------------------------------------- */
/* get identifier into register */
/* -------------------------------------- */
gident(n)
struct NODE *n;
{
int q, r, ty;
struct SYMBOL *s;
struct PSEUDO *p;
s = (n->nop == DOT || n->nop == MEMBER) ? n->right->nid : n->nid;
if ((p=previous)!=NULL && p->ptype==GLOBAL && p->pop==ASGN && optimize) {
if (p->pptr == s) {
if (unrelease(p, r= p->preg))
return r;
}
}
ty = n->ntype->ttype;
r = gaddress(n);
if (ty== ARRAY || ty == STRUCT) return r;
q = getreg();
code4(IDENT, q, r);
release(r);
return q;
}
/* -------------------------------------------- */
/* boolean binary and unary operators */
/* -------------------------------------------- */
glogical(n)
struct NODE *n;
{
struct PSEUDO *p;
int r, r1, r2, lab, val, op;
switch (n->nop) {
case NOT:
r = genstmt(n->left);
r1 = getreg();
code1(IDENT, r1, 1);
code7(n->nop, r, 2); /* branch around if false */
code5(SETF, r1);
release(r);
return r1;
case LAND:
r = getreg();
lab = getlabel();
code5(SETF, r);
gboolean(n->left, lab, 0);
gboolean(n->right, lab, 0);
code1(IDENT, r, 1);
outlab(lab);
return r;
case LOR:
r = getreg();
lab = getlabel();
code1(IDENT, r, 1);
gboolean(n->left, lab, 1);
gboolean(n->right, lab, 1);
code5(SETF, r);
outlab(lab);
return r;
default:
r = getreg();
code1(IDENT, r, 1);
gboolop(n, 0);
code5(SETF, r);
return r;
}
}