Google
 

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

#define	    sd   extern
#include    "cc.g"


/* --------------------------------------------- */
/*	address immediate -> register codes      */
/* --------------------------------------------- */

code3(op, r, s)
struct SYMBOL *s;
{
  if (op==PLUS && previous->ptype==IMMED && previous->preg==r && optimize) {
     switch (previous->pop) {
     case PLUS:
     case IDENT:
          previous->ptype = GADDR;
	  previous->poffset = previous->pvalue;
          previous->pptr = s;
	  previous->pindex = 0;
	  return;
     }
  }
  previous = &codes[maxcode&(MAXCODE-1)];
  previous->ptype = GADDR;
  previous->pop = op;
  previous->preg = r;
  previous->pptr = s;
  previous->poffset = 0;
  previous->pindex = 0;
  maxcode++;
}

/* ------------------------------------ */
/*	register-register indirect      */
/*	(transformed to indexed)	*/
/* ------------------------------------ */

code4(op, r, s)
{
  struct PSEUDO *p, *b, *before();
  struct SYMBOL *ssymbol;
  int    ty, o, soffset;

  if (previous->ptype == IMMED && previous->preg == s) {

      switch (previous->pop) {

          /* fold:   MOVNI  s,const  */
          /*	     OP     r,@s     */
          /*			     */
	  /* into:   OP	    r,const  */

      case NEG:
	   previous->pvalue = -previous->pvalue;
	   /* fall through */

          /* fold:   MOVEI  s,const  */
          /*	     OP     r,@s     */
          /*			     */
	  /* into:   OP	    r,const  */

      case IDENT:
           previous->ptype = RCONST;
           previous->preg = r;
           previous->pop = op;
           release(s);
           return;
      }
  }

  ssymbol = NULL;
  soffset = 0;
  p = previous;
  while (p != NULL) {
      if (p->preg == s) {
          if (p->pop == PLUS) {
	      switch (p->ptype) {
	      case IMMED:
	           soffset += p->pvalue;
	           p->pop = NOP;
		   break;
	      case GADDR:
	           if (ssymbol == NULL) {
		       p->pop = NOP;
		       ssymbol = p->pptr;
		       soffset += p->poffset;
		   }
	      }
	  }
          else if (p->pop < 1000) break;
      }
      p = before(p);
  }
  if (soffset || ssymbol != NULL) {
      o = PLUS;
      if (p->pop == IDENT && p->preg == s && p->ptype == IMMED) {
          soffset += p->pvalue;
	  p->pop = NOP;
	  o = IDENT;
      }
      code3(o, s, ssymbol);
      previous->poffset = soffset;
  }
  if ((p = previous) != NULL && p->preg == s && optimize) {
      if (op == IDENT || tok[op].ttype == ASOP) {
          switch (p->ptype) {
	  case GADDR:
	       switch (p->pop) {
	       case IDENT:
		    if (op == ASGN) {
		        b = before(p);
			if (b->preg == r) {
		            if (b->ptype == GLOBAL && b->pptr == p->pptr) {
		                o = b->pop;
			        if (o==PLUS || o==MINUS || o==MPLY ||
			            o==AND  || o==OR || o==XOR || o==DIV) {
	
			            /* fold:  	OP    R,addr */
			            /*		MOVEM R,addr */
				    /*			     */
		   	            /* into:	OPB   R,addr */

			            b->ptype = BOTH;
				    b->poffset = p->poffset;
				    b->pindex = 0;
			            p->pop = NOP;	/* poof! */
			            return r;
			        }
			    }
			    else  if (b->ptype == ONEREG && b->pop == SETZ) {

				/* fold:    SETZ   R,     */
				/*	    MOVEM  R,...  */
				/*			  */
				/* to:      SETZB  R,...  */

				p->pop = NOP;		/* poof! */
				b->ptype = BOTH;
				b->pptr = p->pptr;
				b->pindex = 0;
				b->poffset = p->poffset;
				return r;
			    }
			}
		    }

		    /*  fold:    	MOVEI   S,addr */
		    /*		        MOVE(M) R,@S   */
		    /*  into:		MOVE(M) R,addr */

  	            p->ptype = GLOBAL;
               	    if (s != r) regis[s] = -1;
	       	    p->pop = op;
	 	    p->preg = r;
		    p->pindex = 0;
		    return;

	       case PLUS:

		    /*  fold:    	ADDI    S,addr+offset    */
		    /*		        MOVE(M) R,@S             */
		    /*  into:		MOVE(M) R,addr+offset(S) */

	       	    p->ptype = MINDEXED;
	            p->pop = op;
	            p->preg = r;
	            p->pindex = s;

		    if (op == ASGN) {
		        /* one more chance ... */
		        b = before(p);
		        if (b->ptype==ONEREG && b->pop==SETZ && b->preg==r) {

			    /* fold:    SETZ   R,       */
			    /*          MOVEM  R,...    */
			    /*				*/
			    /* into:    SETZB  R,...    */

		            b->pop = NOP;   /* poof! */
		    	    p->pop = SETZ;
			    p->ptype = BOTH;

			}
		    }
	            return;
	       }
	  case IINDEXED:
	       if (p->pop == IDENT) {
	           
		   /* fold:      MOVEI	  S,offset(SP)  */
		   /*		 MOVE(M)  R,@S		*/
		   /*					*/
		   /* into:	 MOVE(M)  R,offset(SP)	*/
		   
		   p->ptype = INDEXED;
		   if (s != r) regis[s] = -1;
		   p->pop = op;
		   p->preg = r;

		   if (op == ASGN) {   /* one more chance ... */
		       b = before(p);
		       if (b->ptype==ONEREG && b->pop==SETZ && b->preg==r) {

			   /* fold:    SETZ   R,       */
			   /*          MOVEM  R,...    */
			   /*				*/
			   /* into:    SETZB  R,...    */

		           b->pop = NOP;   /* poof! */
		    	   p->pop = SETZ;
			   p->ptype = BOTH;
		       }
		   }
		   return;
	       }
	       break;

	  case GLOBAL:
	  case INDEXED:
	       if (p->pop == IDENT) {


		    /* transform:	MOVE    S,loc    */
		    /*			MOVE(M) R,@S	 */
		    /* to:		MOVE(M) R,@loc   */

		   p->ptype = MINDIRECT;
		   if (s != r) regis[s] = -1;
		   p->pop = op;
		   p->preg = r;
		   return;
	       }
	       break;

	  case IMMED:
	       if (p->pop == PLUS) {

		    /*  transform:	ADDI    S,Offset    */
		    /*		 	MOVE(M) R,@S        */
		    /*  to:		MOVE(M) R,Offset(S) */

      	           p->ptype = INDEXED;
                   if (s != r) regis[s] = -1;
	           p->pop = op;
	           p->preg = r;
	           p->pindex = s;
	           return;
		}
	  }
      }
      else {
          if (p->pop == IDENT) {
              ty = p->ptype;
	      if (ty == GLOBAL || ty == GADDR) {
  	          if (s != r) regis[s] = -1;
	          p->ptype = (ty == GLOBAL) ? MINDIRECT : GLOBAL;
	          p->pop = op;
	          p->preg = r;
		  p->poffset = 0;
		  p->pindex = 0;
	          return;
	      }
	  }
      }
  }
  previous = &codes[maxcode&(MAXCODE-1)];
  previous->ptype = INDEXED;
  previous->pop = op;
  previous->preg = r;
  previous->poffset = 0;
  previous->pindex = s;
  maxcode++;
  release(s);
}