Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_FS_1_19910112 - c/old/kc/cc8a.c-tenex
There are no other files named cc8a.c-tenex in the archive.
/* cc8A.c -- Code generator TOPS-20 (contd)   (C) 1981  K. Chen */

#define	    sd   extern
#include    "cc.g"

/* ---------------------------- */
/*	generate real code      */
/* ---------------------------- */

realcode(n)
{
  struct PSEUDO *p;
  char *op, lstr[10], *t;
  int  opr, typ, i, big;

  p = &codes[n&(MAXCODE-1)];

  if ((opr = p->pop) >= 1000) {
      switch (opr) {
      case RELEASE:
           if (p->preg < 20) {
	       if (p->preg >= 16) {
	           i = regis[p->preg];
	           if (i >= 0) {
		       regis[i] = -1;
		       regis[p->preg] = -1;
	           }
	       }
	       else regis[p->preg] = -1;
	   }
	   p->pop = CODED;
	   break;
      case GLABEL:
	   outsym(p->plabel);
	   op = (p->plabel[0] == '$' && FAIL) ? "::\n" : ":\n";
	   outstr(op);
	   break;
      case CLABEL:
           outstr("\t$");
	   outnum(p->pvalue);
	   outc('\n');
	   break;
      case CVALUE:
           outstr("\t");
	   outnum(p->pvalue);
	   outc('\n');
	   break;
      case CINIT:
           outstr("\tMOVE\t2,$");
	   outnum(p->pvalue);
	   outc('\n');
	   break;
      }
      return 1;
  }

  big = 0;
  typ = p->ptype;

  if (typ == RCONST) {
      switch (opr) {
      case ADJSP:
      case LSHFT:
      case RSHFT:
           break;
      default:
           if (p->pvalue > 0777777 || p->pvalue < 0)
               opr = directop(opr);
      }
  }
  if (typ == IINDEXED && p->pop == FNARG) {
       outstr("\tMOVEI");
       outreg(14);
       if (i = p->poffset) outnum(i);
       outindex(p->pindex);
       outstr("\n");
  }

#ifdef NOADJSP
  if (opr == ADJSP) {
	if (typ != RCONST) {
	   printf("\nUnimplemented ADJSP!\n");
	   return(0);
	}
	if ((i = p->pvalue) < 0) {
	   outstr("\tSUB");
	   i = -i;
	}
	else outstr("\tADD");
	outreg(p->preg);
	outc('[');
	outnum(i);
	outstr(",,");
	outnum(i);
	outc(']');
	nl();
	return(0);
  }
#endif NOADJSP
#ifdef NOADJBP
  if (opr == ADJBP) {
      switch (typ) {
      case REGIS:
           i = p->pr1;
	   break;
      case GLOBAL:
      case INDEXED:
      case BYTEPOINT:
           i = p->preg;
	   break;
      default:
	   printf("\nUnimplemented ADJBP!\n");
	   return 0;
      }
      outstr("\tMOVE\t16,");
      oreg(i);
      outstr("\n\tASH");
      outreg(i);
      outstr("-2\n\tADD");
      outreg(i);

      switch (typ) {
      case REGIS:
	   oreg(p->pr2);
           break;

      case GLOBAL:
           if (*p->pptr->sname) {
	       outsym(p->pptr->sname);
               outoffset(p);
           }
           else outnum(p->poffset);
           outindex(p->pindex);
           break;

      case INDEXED:
           if (p->poffset) outnum(p->poffset);
           outindex(p->pindex);
	   break;

      case BYTEPOINT:
           outc('[');
           outnum(p->poffset>>18);
           outstr(",,");
           outsym(p->pptr->sname);
           outoffset(p);
           outc(']');
           break;
      }
      outstr("\n\tANDI\t16,3\n\tSUB");
      outreg(i);
      outstr("$BYTE(16)\n\tSKIPGE\t,");
      oreg(i);
      outstr("\n\tADD");
      outreg(i);
      outstr("[440000,,000001]\n");
      return 0;
  }
#endif

  if (opr == ADJBP) {
      i = p->preg;
      if (i > 15) i = regis[i];
      if (i == 0) {
          outstr("\tMOVE\t16,0\n");
	  p->preg = 14;
      }
  }
  tab();
  outstr(dec20op[opr]);

  switch (typ) {
  case IMMED:
       if (opr == FNARG) {	/* DEC-20 operators with no immediate fields */
           outreg(p->preg);
	   outc('[');
           outnum(p->pvalue);
	   outc(']');
  	   break;
       }
       if (p->pvalue > 0777777 || p->pvalue < 0)
           big = 1;
       else
           outc('I');

       outreg(p->preg);
       if (big) {
	   outc('[');
	   outnum(p->pvalue);
           outc(']');
       }
       else outnum(p->pvalue);
       break;

  case RCONST:
       switch (opr) {
       case LSHFT:
       case RSHFT:
       case ADJSP:
            break;
       default:
            big = (p->pvalue > 0777777 || p->pvalue < 0);
       }
       outreg(p->preg);
       if (big) {
	   outc('[');
	   outnum(p->pvalue);
           outc(']');
       }
       else outnum(p->pvalue);
       break;

  case BYTEPOINT:
       outreg(p->preg);
       outc('[');
       outnum(p->poffset>>18);
       outstr(",,");
       outsym(p->pptr->sname);
       outoffset(p);
       outc(']');
       break;

  case ISINGLE:
       tab();
       if (p->preg >= 0) {
	   outc('(');
           oreg(p->preg);
	   outc(')');
           break;
       }
       outc('@');
       outsym(p->pptr->sname);
       outoffset(p);
       break;

  case SINGLE:
       tab();
       if (p->preg >= 0) {
           oreg(p->preg);
           break;
       }
       if (p->pptr != NULL) {
	   outsym(p->pptr->sname);
	   outoffset(p);
       }
       else if (p->poffset) outnum(p->poffset);
       outindex(p->pindex);
       break;

  case GADDR:
       if (opr == FNARG) {	/* DEC-20 operators with no immediate fields */
           outreg(p->preg);
	   outc('[');
           outsym(p->pptr->sname);
	   outc(']');
  	   break;
       }
       outc('I');
       outreg(p->preg);
       if (*p->pptr->sname) {
	   outsym(p->pptr->sname);
           outoffset(p);
       }
       else outnum(p->poffset);
       break;

  case REGIS:
       outreg(p->pr1);
       oreg(p->pr2);
       break;

  case ONEREG:
       outreg(p->pr1);
       break;

  case IINDEXED:
       if (p->pop == FNARG) {
           outreg(SP);
	   outnum(14);
           break;
       }
       outc('I');
       outreg(p->preg);
       if (i = p->poffset) outnum(i);
       outindex(p->pindex);
       break;

  case INDEXED:
       outreg(p->preg);
       if (i = p->poffset) outnum(i);
       outindex(p->pindex);
       break;

  case BOTH:
       outc('B');
  case GLOBAL:
  case MINDEXED:
       outreg(p->preg);
       if (*p->pptr->sname) {
	   outsym(p->pptr->sname);
           outoffset(p);
       }
       else outnum(p->poffset);
       outindex(p->pindex);
       break;

  case BLABEL:
       outstr("\t@$");
       outnum(p->poffset);
       outindex(p->pindex);
       break;

  case DLABEL:
       outreg(p->preg);
       outc('$');
       outnum(p->poffset);
       outindex(p->pindex);
       break;

  case INDIRECT:
       outreg(p->pr1);
       outc('@');
       oreg(p->pr2);
       break;

  case MINDIRECT:
       outreg(p->preg);
       outc('@');
       if (*p->pptr->sname) {
	   outsym(p->pptr->sname);
           outoffset(p);
       }
       else outnum(p->poffset);
       outindex(p->pindex);
       break;

  case LAB:
       if (opr != GOTO) {
           outreg(p->preg);
       }
       else tab();
       maklabel(lstr, p->pvalue);
       outsym(lstr);
       break;

  case BR:
       outreg(p->preg);
       if (p->pvalue >= 0) {
	   opr = p->pvalue;
	   op = ".+";
       }
       else {
	   opr = -p->pvalue;
	   op = ".-";
       }
       outstr(op);
       outnum(opr);
       break;
  }
  nl();
  return 0;
}

outreg(n)
{
  putc('\t', out);
  oreg(n);
  putc(',', out);
}

oreg(n)
{
  if (n > 15) n = regis[n];
  outnum(n);
}

outindex(n)
{
  if (n) {
      outc('(');
      outnum(n);
      outc(')');
  }
}

outoffset(p)
struct PSEUDO *p;
{
 int i; 

 if (i = (p->poffset & 0777777)) {
     if (i > 0) outc('+');
     outnum(i);
 }
}

tab()   { putc('\t', out);}
comma() { putc(',',  out);}
nl()    { putc('\n', out);}