Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/cc84.c
There are no other files named cc84.c in the archive.
/* cc84.c -- Code generator TOPS-20 (contd) (C) 1981 K. Chen */
#define sd extern
#include "cc.g"
/* ------------------------------------------- */
/* generate code for unary operators */
/* ------------------------------------------- */
gunary(n)
struct NODE *n;
{
int q, r, s;
struct PSEUDO *p;
struct NODE *nod;
switch (n->nop) {
case PINC:
return incdec(n, INC, 1, 0);
case PDEC:
return incdec(n, DEC, 1, 0);
case INC:
case DEC:
return incdec(n, n->nop, 0, 0);
case PTR:
q = genstmt(nod=n->left);
r = getreg();
if (charpointer(nod->ntype)) {
code0(LDB, r, q);
}
else {
if (q > 15) {
s = getreg();
code0(IDENT, s, q);
code4(IDENT, r, s);
release(s);
}
else code4(IDENT, r, q);
}
release(q);
break;
case ADDR:
r = gaddress(nod=n->left);
if (nod->nop == IDENT && nod->ntype == chartype) {
previous->pop = IDENT;
previous->ptype = BYTEPOINT;
previous->poffset = LSBYTE;
}
break;
case NEG:
r = genstmt(n->left);
code0(NEG, r, r);
break;
case COMPL:
r = genstmt(n->left);
code0(COMPL, r, r);
break;
default:
fprintf(stderr,"Unimplemented unary op -- %d.\n", n->nop);
}
return r;
}
/* ----------------------- */
/* function calls */
/* ----------------------- */
gcall(n)
struct NODE *n;
{
struct NODE *l;
int r, s, zero, z, narg, pushed[16];
flushcode(0);
r = 0;
if (regis[r] >= 0) { /* Determine if AC0 needs */
zero = getreg(); /* saving and relocating */
regis[zero] = -1;
z = regis[r];
regis[z] = zero;
regis[r] = -1;
}
else {
zero = -1;
z = 0;
}
for (r = 2; r < 15; r++) { /* Determine if registers */
pushed[r] = 0;
if (regis[r] >= 0) { /* need saving */
code0(FNARG, SP, r);
stackoffset = stackoffset+1;
pushed[r] = 1;
}
else if (r == zero) {
code0(FNARG, SP, 0);
stackoffset = stackoffset+1;
pushed[r] = 1;
}
}
if (z) regis[zero] = z;
l = n->right;
narg = 0;
if (l != NULL) { /* function arguments */
while (1) {
if (l->nop == EXPRESS) {
if (l->right->nop == IDENT && l->right->ntype->ttype == STRUCT) {
fprintf(stderr, "Warning -- pushing struct.\n");
}
else {
s = genstmt(l->right);
code0(FNARG, SP, s);
stackoffset = stackoffset+1;
narg = narg - 1;
release(s);
}
l = l->left;
}
else {
s = genstmt(l);
if (previous->pop == SETZ) {
previous->ptype = IMMED;
previous->pop = IDENT;
previous->pvalue = 0;
}
code0(FNARG, SP, s);
stackoffset = stackoffset+1;
narg = narg - 1;
release(s);
break;
}
}
}
flushcode(0);
r = getzero();
code2(CALL, SP, n->left->nid->sname);
if (narg) {
stackoffset = stackoffset + narg;
code8(ADJSP, SP, narg);
}
for (s = 14; s > 1; s=s-1) { /* Determine if registers */
if (pushed[s]) { /* need restoring */
code0(POP, SP, s);
stackoffset = stackoffset - 1;
}
}
return r;
}
/* ---------------------- */
/* if statement */
/* ---------------------- */
gif(n)
struct NODE *n;
{
int true, false;
struct NODE *nthen, *nelse, *body, *l;
body = n->right;
nthen = body->left;
nelse = body->right;
l = n->left;
if (nthen->nop == BREAK && nelse == NULL) { /* if ... break */
gboolean(l, brklabel, 1);
return;
}
false = getlabel();
if (l->nop == ICONST) {
if (l->niconst)
release(genstmt(nthen));
else
if (nelse != NULL) release(genstmt(nelse));
return;
}
gboolean(l, false, 0);
if (nthen) release(genstmt(nthen));
if (nelse != NULL) {
true = getlabel();
code6(GOTO, 0, true);
}
outlab(false);
if (nelse != NULL) {
release(genstmt(nelse));
outlab(true);
}
}
/* ------------------------- */
/* while statement */
/* ------------------------- */
gwhile(n)
struct NODE *n;
{
int saveb, savel, k;
savel = looplabel;
saveb = brklabel;
looplabel = getlabel();
brklabel = getlabel();
outlab(looplabel);
if ((k = n->left->nop) != ICONST) {
gboolean(n->left, brklabel, 0);
}
if ((k != ICONST || n->left->niconst)) {
if (n->right != NULL) release(genstmt(n->right));
code6(GOTO, 0, looplabel);
}
outlab(brklabel);
brklabel = saveb;
looplabel = savel;
}
/* ---------------------- */
/* do statement */
/* ---------------------- */
gdo(n)
struct NODE *n;
{
int saveb, savel, k;
savel = looplabel;
saveb = brklabel;
looplabel = getlabel();
brklabel = getlabel();
outlab(looplabel);
if (n->right) release(genstmt(n->right));
if ((k = n->left->nop) != ICONST) {
gboolean(n->left, looplabel, 1);
}
else if (n->left->niconst)
code6(GOTO, 0, looplabel);
outlab(brklabel);
brklabel = saveb;
looplabel = savel;
}
/* ----------------------- */
/* for statement */
/* ----------------------- */
gfor(n)
struct NODE *n;
{
struct NODE *cond, *body, *init, *incr;
int saveb, savel, k, toplabel;
savel = looplabel;
saveb = brklabel;
looplabel = getlabel();
brklabel = getlabel();
cond = n->left;
body = n->right;
incr = cond->right->left;
cond = cond->left;
init = cond->left;
cond = cond->right;
if (init != NULL) release(genstmt(init));
toplabel = getlabel();
outlab(toplabel);
if (cond != NULL) gboolean(cond, brklabel, 0);
if (body != NULL) {
release(genstmt(body));
outlab(looplabel);
}
if (incr != NULL) release(genstmt(incr));
code6(GOTO, 0, toplabel);
outlab(brklabel);
brklabel = saveb;
looplabel = savel;
}
/* ------------------------------------------ */
/* increment/decrement instructions */
/* ------------------------------------------ */
incdec(n, op, pre, addr)
struct NODE *n;
{
struct NODE *nod;
struct PSEUDO *p;
int opt, r, q, ptr, size;
nod = n->left;
size = n->nsize;
ptr = charpointer(nod->ntype);
if (nod->nop == IDENT) { /* ++ident */
if (pre) {
increment(op, -1, ptr, nod->nid, size);
r = gident(nod);
}
else {
r = gident(nod);
increment(op, -1, ptr, nod->nid, size);
}
return r;
}
r = gaddress(nod); /* get address of object */
opt = optimize;
optimize = 0;
if (pre){
r = increment(op, r, ptr, NULL, size); /* pre-increment code */
}
q = getreg();
code4(IDENT, q, r);
if (!pre) {
p = &codes[(maxcode-1)&(MAXCODE-1)];
if (p->pop == RELEASE && p->preg == r) p->pop = NOP;
r = increment(op, r, ptr, NULL, size); /* post-increment */
}
release(r);
optimize = opt;
return q;
}
/* ---------------------------------------------------- */
/* output code to indirectly increment object */
/* ---------------------------------------------------- */
increment(op, r, ptr, s, size)
struct SYMBOL *s;
{
int q, i;
if (ptr) {
if (op == INC) { /* byte inc/dec */
if (r >= 0) {
if (size == 1) {
code10(IBP, r, NULL);
return r;
}
else {
q = getreg();
code1(IDENT, q, size);
code4(ADJBP, q, r);
code4(ASGN, q, r);
return q;
}
}
else {
switch (s->sclass) {
case SARG:
case SAUTO:
i = (s->sclass == SARG) ? -(s->svalue+stackoffset)
: s->svalue-stackoffset+1;
if (size == 1)
code14(IBP, i);
else {
q = getreg();
code1(IDENT, q, size);
code12(ADJBP, q, i);
code12(ASGN, q, i);
release(q);
}
break;
default:
if (size == 1)
code11(IBP, -1, s);
else {
q = getreg();
code1(IDENT, q, size);
code2(ADJBP, q, s);
code2(ASGN, q, s);
release(q);
}
}
}
}
else { /* decrement Byte pointer */
if (r >= 0) {
q = getreg();
code1(NEG, q, size);
code4(ADJBP, q, r);
code4(ASGN, q, r);
return q;
}
else {
switch (s->sclass) {
case SARG:
case SAUTO:
i = (s->sclass == SARG) ? -(s->svalue+stackoffset)
: s->svalue-stackoffset+1;
q = getreg();
code1(NEG, q, size);
code12(ADJBP, q, i);
code12(ASGN, q, i);
release(q);
break;
default:
q = getreg();
code1(NEG, q, size);
code2(ADJBP, q, s);
code2(ASGN, q, s);
release(q);
}
}
}
return r;
}
else {
if (r >= 0) {
if (size != 1)
op = (op == INC) ? PLUS : MINUS;
if (size == 1) {
code10(op, r, NULL);
return r;
}
else {
code1(op, r, size);
return r;
}
}
else {
if (size != 1)
op = (op == INC) ? ADDM : SUBM;
switch (s->sclass) {
case SAUTO:
i = s->svalue-stackoffset+1;
if (size == 1)
code14(op, i);
else {
q = getreg();
code1(IDENT, q, size);
code12(op, q, i);
release(q);
}
break;
case SARG:
i = -(s->svalue+stackoffset);
if (size == 1)
code14(op, i);
else {
q = getreg();
code1(IDENT, q, size);
code12(op, q, i);
release(q);
}
break;
default:
if (size == 1)
code11(op, -1, s);
else {
q = getreg();
code1(IDENT, q, size);
code2(op, q, s);
release(q);
}
}
}
}
}